Question

Given a base class for multiple derived class, the goal was to create a wrapper class that allowed an STL container to see objects with the base interface, event though different derived classes may actually be added to the container. (See Retrieve data from heterogeneous std::list).

After some tinkering, I came up with a new derived class that was a wrapper around a unique_ptr to the base class. However, the move constructor has me confused.

class Base {
    friend class BaseWrapper;
    virtual Base * clone () const = 0;
public:
    virtual ~Base () {}
    //... public interface
};

class Derived : public Base {
    //... specific members for derived class
    Base * clone () const { return new Derived(*this); }
public:
    //... implement public interface
};

class BaseWrapper : public Base {
    std::unique_ptr<Base> ptr_;
    Base * clone () const { return ptr_->clone(); }
public:
    BaseWrapper (const Base &b) : ptr_(b.clone()) {}
    //... implement public interface by forwarding to ptr_
};

typedef std::list<BaseWrapper> BaseList;

int main () {
    BaseList l;
    l.push_back(Derived());
}

This does not compile with g++ 4.7.2.

Now, in order to use BaseWrapper, I can implement a public move constructor like this:

    BaseWrapper (BaseWrapper &&bw) { ptr_.swap(bw.ptr_); }

And this works fine. But, if I make it private, it will not compile.

However, I found that instead of the above, I can instead define a private "copy" constructor (making it public also works, of course):

    BaseWrapper (BaseWrapper &bw) { ptr_.swap(bw.ptr_); }

Could someone tell me if this was supposed to work, and why or why not? If it is supposed to work, why can I not make the move constructor private?

You can follow this link to the toy program illustrating the above in a more complete way.

Was it helpful?

Solution

[removed the erroneous diagnostic]

That actually compiles on gcc 4.8. It seems like gcc 4.7 takes BaseWrapper (const Base &) as a copy constructor(which is actually not), and implicitly deletes the move constructor(which would be expected behaviour if it were indeed a copy constructor).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top