Boost logo

Boost :

From: Ulrich Eckhardt (doomster_at_[hidden])
Date: 2007-06-01 00:40:07


On Thursday 31 May 2007 20:09:37 Gmane wrote:
> as sparent_at_[hidden] pointed out in
> <http://svn.boost.org/trac/boost/ticket/979>, the EBO is not possible in
> some cases. I fixed the operators library, but now I wonder if we should
> fix boost::noncopyable as well.
>
> Consider:
>
> class A : boost::noncopyable {};
> class B : boost::noncopyable { A a; };
>
> now sizeof(B)==2 instead of the expected 1. To fix it, we have to change
> the interface (or at least allow an alternative interface). Example with
> the interface I'd like to suggest:
>
> class A : boost::noncopyable_<A> {};
> class B : boost::noncopyable_<B> { A a; };
>
> now sizeof(B)==1, as expected.
>
> The crucial point of such a change is IMHO the interface. Breaking
> noncopyable is bad, so I'd like to add noncopyable_<T> and make
> noncopyable a typedef to noncopyable_<void>. This should provide
> backwards compatibility and provides users with a better, but less brief
> alternative in case they need the additional EBO opportunity. Comments?

I added a comment inline which I hope explains the rationale for this class,
because it is far from obvious IMHO. If the reasons there are wrong, please
correct me. Other than that, I'd suggest naming it noncopyable_base<T>.

> namespace noncopyable_impl // prevent unintended ADL
> {
      /* baseclass for noncopyable objects

      Usage:
        // A is noncopyable and non-assignable now
        class A: noncopyable_<A>
        {};

      Note: the reason this is a template and not a plain class like
      it used to be is that it improves EBO. If an (otherwise empty)
      object inherits noncopyable and includes (via a member)
      noncopyable, too, the compiler is required to assign each a
      unique address (TODO: insert standard reference), thus the
      resulting size of the object must be at least 2.
      If the two non-copyable subobjects are of different types (as
      they are when templated) they are allowed to have the
      same address and the compiler can fully exploit EBO. */
> template< typename > class noncopyable_
> {
> protected:
> noncopyable_() {}
> ~noncopyable_() {}
> private:
> noncopyable_( const noncopyable_& );
> const noncopyable_& operator=( const noncopyable_& );
> };
> typedef noncopyable_<void> noncopyable;
> }
>
> using namespace noncopyable_impl;

Why this? I guess it is intended to prevent ADL, right? Can you point me to a
rationale for this?

thanks

Uli


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk