элемент unique_ptr, личный конструктор копирования и конструктор перемещения

Учитывая базовый класс для нескольких производных классов, цель состояла в том, чтобы создать класс-оболочку, который позволял бы контейнеру STL видеть объекты с базовым интерфейсом, хотя на самом деле различные производные классы могут фактически добавляться в контейнер. (Увидеть Получить данные из разнородного std :: list).

После некоторой обработки я придумал новый производный класс, который был оберткой вокруг unique_ptr в базовый класс. Тем не менее, конструктор перемещения меня запутал.

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());
}

Это не компилируется с g ++ 4.7.2.

Теперь для того, чтобы использовать BaseWrapperЯ могу реализовать публичный конструктор перемещения следующим образом:

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

И это прекрасно работает. Но если я сделаю это приватным, это не скомпилируется.

Тем не менее, я обнаружил, что вместо вышесказанного, Вместо этого я могу определить личный конструктор копирования (обнародование также работает, конечно):

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

Может кто-нибудь сказать мне, если это должно было сработать, и почему или почему нет? Если он должен работать, почему я не могу сделать конструктор перемещения закрытым?

Вы можете следовать эта ссылка в игрушечной программе, иллюстрирующей вышесказанное в более полной форме.

4

Решение

[убрал ошибочную диагностику]

Это на самом деле компилируется на GCC 4.8. Похоже гкк 4.7 берет BaseWrapper (const Base &) как конструктор копирования (который на самом деле не является), и неявно удаляет конструктор перемещения (что было бы ожидаемым поведением, если бы он действительно был конструктором копирования).

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]