From: Maarten Kronenburg (M.Kronenburg_at_[hidden])
Date: 2006-05-26 15:37:01
"Sebastian Redl" <sebastian.redl_at_[hidden]> wrote in message
> Maarten Kronenburg wrote:
> >Thanks for your comments.
> >When an implementation is very slow,
> >it will not be useful at all, and not be used.
> If a compiler ships with a slow standard library, there will be pressure
> on the vendor to make a better library. There is no need to specify
> complexity bounds that a vendor will do his best to reach anyway.
> I think the way integer is specified should follow the guidelines of how
> string is specified, as both try to act like a built-in type.
> There are no complexity bounds on, say, string::find_first_of, no
> requirement that it be O(N+M), where N is the string's length and M the
> number of characters being searched for. Yet it is certainly possible to
> implement it this way, instead of the naive O(N*M). If the library
> vendor is smart and there's a need for speed, it will be implemented in
> a good way. If there are tradeoffs between different functions,
> different libraries will offer different tradeoffs or a library will
> have a compile-time switch to choose. However, by specifying the
> complexity of a given function, you're limiting the implementer. This is
> particularly significant in a library full of possibly complex
> algorithms such as integer.
Thanks for your comments.
When I relax the complexities then they will say that
I allowed for too slow implementations.
Let's keep the complexities in, and at least in my
implementation they are fulfilled.
> >Derivation is a part of C++, so in my opinion
> >users must be able to derive from class integer
> >to make an integer with special properties.
> >How would you explain to a user that whatever
> >he/she does with integer, derivation is not an option,
> >because the destructor does not happen to be virtual.
> >This is what it boils down to in the end.
> Well, how do you explain it to users of std::string? The class has been
> quite happy without virtual destructors.
Then I ask you how to add two strings with different
> >Once again I argue that an unsigned integer is an integer,
> >and a modular integer is an integer.
> You are wrong here. Of course, given the abstract concept of an integer,
> an unsigned integer IS-A integer - just as a signed integer is. However,
> the integer you specify is not an abstract concept, but a concrete class
> - misnamed, actually, because it's a signed integer. (In the same way as
> int is assumed to be signed by default.)
> You can either make integer abstract and derive signed_integer and
> unsigned_integer from it. Or you can make it concrete, follow the core
> language in the implicit assumption that it is actually a signed
> integer, and not have the IS-A relationship between unsigned_integer and
> integer, thus not deriving one from the other. After all, an unsigned
> integer IS-NOT-A signed integer.
For an abstract base class, derivation is mandatory.
This is not what I want, because I want non-demanding
users to be able to use the class integer without derivation.
On the other hand I also want demanding users to be able
to use derivation for defining integers with specific properties
such as an unsigned_integer or a modular_integer,
and use mixed expressions.
When I make the class concrete then users will never
be able to derive from it, unless they make a new class
with an integer data member and start all over again.
I have thought this through, and I think the way it is,
it serves both non-demanding and demanding users
best with flexibility if needed.
> >An unsigned int is actually a modular int with modulus 2^32.
> >When an integer with a certain allocator must be used
> >in an expression with an integer with another allocator,
> >then run-time polymorphism is the only option.
> Where did the allocator come into this discussion? Anyway, compile-time
> polymorphism (i.e. templates) is also an option - make all binary or
> higher-order operations that work on integers templated on the
> allocators of all operands, put the burden of merging the allocation
> correctly on the implementers and specify which allocator is used by the
> Or do it as std::string does and simply don't allow cross-use of
> different allocator types. (This lack of interoperability has often been
> cited as a shortcoming, though. The solution here is to make the
> allocator runtime-polymorphic, not the integer.)
If I don't allow cross-use of different allocators, then no mixed
expressions are possible. Why should the use of a different allocator
for an integer prevent it from being added to an integer with
The integer needs to be run-time polymorphic for the same reason:
why should it not be possible to add an unsigned integer to a
> >The integer as specified will strictly mimic the int.
> >As mentioned to others I will add a unspecified-bool
> >conversion to be able to use if( x ) with x an integer.
> >But making a "basic" integer and then making it a data member
> >of a "full" integer, I do not recommend that strategy.
> >I recommend to make the interface right and complete
> >from the beginning.
> Like std::string did? You can't make everyone happy with any interface,
> but a minimal interface can at least claim a philosophy.
In my opinion the current design serves both non-demanding users
(they can just use the class integer) and demanding users
(they can derive from class integer, use an allocator, and use
Then (I hope) as many people as possible will be happy.
> What C++ lacks here, IMO, is some sort of mixin concept - effectively a
> way to call free functions as if they were members of a class.
In my opinion C++ offers so many options that we have these
> Sebastian Redl
> Unsubscribe & other changes: