On Fri, Mar 30, 2012 at 8:11 AM, Szymon Gatner <szymon.gatner@gmail.com> wrote:
Hi,

I am implementing custom smart pointer with move semantics and I am
having problems with implementing move constructor with template
param. In fact clone_ptr presented in docs suffers from that issue
also. This code:

class B {}
class D: public B {}

clone_ptr<D> makeD();

void main()
{
clone_ptr<B> b = makeD()  // gives "error C2440: 'initializing' :
cannot convert from 'clone_ptr<T>' to 'clone_ptr<T>'"
}


adding

 template <class U>
 clone_ptr(BOOST_RV_REF(clone_ptr<U>) p)            //Move constructor
   : ptr(p.ptr) { p.ptr = 0; }

to clone_ptr class does not help. Additional c-tor seems to be
ignored. How to fix that?

Unfortunately, you can't catch rvalues of a move-emulation-enabled type in a deduced context as you've tried to above (in C++03). If you want some ideas on how to get something like this to work, search the Boost developer list under the messages subject "[boost] [move] new rvalue reference emulation".

The easiest solution, though, is simply to split the construction into two steps:

clone_ptr<D> d = makeD();
clone_ptr<B> b = boost::move(d);

(This still requires the additional constructor you've given above!) I *think*, due to RVO, there shouldn't be any overhead with the above pair of statements compared with rolling everything into a single statement.

If this doesn't fulfill your needs, I suggest reading through the thread given above in the Boost developer list.

HTH,

- Jeff