On Wed, 2004-02-11 at 01:59, Gabriel Dos Reis wrote:
Matt Austern <austern@apple.com> writes:
| On Feb 9, 2004, at 6:20 PM, Gabriel Dos Reis wrote:
|
| > Matt Austern <austern@apple.com> writes:
| >
| > | I'm afraid you're right too. Fortunately, I really do only
mean "a
| > | bit" more
| > | complicated. The solution is pretty simple: instead of
inheriting
| > | directly
| > | from the allocator, instead inherit from a thin wrapper class
that
| > | provides
| > | nothing but the allocator functions we care about.
| >
| >
| > Just to make sure I understand your suggestion. In doing so, how
do
| > we prevent the "virtual function is a sin you inherit from your
| > descendents" syndrom and benefit at the same time from the empty
base
| > optimization?
| >
| > The solution I'm thinking of would be:
| >
| > template<class Allocator>
| > WrapAllocator {
| > Allocator allocator;
| > // standard allocator interface goes here
| > // as forwarding functions to Allocator
| > // ...
| > };
| >
| > template<class T, class Allocator = allocator<T> >
| > struct vector : private WrapAllocator<Allocator> {
| > // ...
| > };
| >
| > Is that what you're alluding to?
|
| Basically, yes. The two ways in which this isn't *exactly* what I
| have in mind:
| (1) It won't be the full standard allocator interface, only the
| useful part. (i.e. "allocate" and "deallocate".)
| (2) Two template parameters, not one. As long as we have to
| introduce this wrapper class anyway, may as well make it
| do double duty by having it take care of the icky rebind
| stuff.
OK, I did my homework. I think it is possible to use the inheritance
trick and benefit from the empty base class optimization and still not
get trapped by Dhruv's example.
(1) Say don't do that. I'm not sure if this is going to be
acceptable answer. Certainly it is not for a testsuite.
But, I don't know whether outsitde of the testsuites areas, it
is
acceptable. I would think it is, but nobody knows what C++
programmers do.
(2) instead of using containment followed by inheritance, use
inheritance+uglification followed by containment+delegation.
What's inheritance+uglification? I'm mainly interested in uglification?
If you have containment anywhere in the picture, won't the EBO get
nullified? AFAICS, containment + delagation is the same as your earlier
proposal? Or I have misunderstood something?
Do people have better alternatives?
I have cc'd you the patch. It mainly does this:
1. A new IMPL class that encapsulates the implementation ie. _M_start,
_M_finish and _M_end_of_storage, and also derived from the _Alloc
parameter. Thus, the rest of the vector's implementation now refer to
_M_start, etc... as _M_impl._M_start, etc...
2. The vector does not get derived in any way from the allocator, and
so
the clear() problem is avoided. Also, the allocator may have members
push_back, pop_back, etc...
3. The extra code for delegation is not required.
--
-Dhruv Matani.
http://www.geocities.com/dhruvbird/