Для аналогичного примера смотрите этот пример, который тоже должен потерпеть неудачу
unique_ptr<Base> testBase = move(testDerived);
Проблема здесь в том, как реализована семантика перемещения: «конструктор копирования» использует неконстантную ссылку, поэтому не можетпривязать к временным.Чтобы все еще «уйти» от временных фигур, в классе есть функция преобразования (следующие на самом деле просто концептуальные - они могут быть по-разному реализованы в деталях):
operator rv<T>() { return rv<T>(*this); }
И конструктор примет этот объект:
unique_ptr(rv<T> r):ptr_(r.release()) { }
Вот пример, который не работает по той же причине:
// move helper. rv<> in unique_ptr
struct E { };
// simulates a unique_ptr<D>
struct D { };
// simulates the unique_ptr<B>
struct A {
A() { }
// accepts "derived" classes. Note that for unique_ptr, this will need that
// the argument needs to be copied (we have a by-value parameter). Thus we
// automatically ensure only rvalue derived-class pointers are accepted.
A(D) { }
// these will accept rvalues
A(E) { }
operator E() { return E(); }
private:
A(A&); // private, error if passed lvalue
};
Теперь рассмотрим этот код:
// allowed: goes: D -> A(D)
A a((D()));
// compile failure. Goes:
// D -> A(D) -> A(E)
A a = D();
При инициализации копирования сначала преобразуется в A
,Но затем временный объект A
снова пытаются скопировать в конечный объект.Для этого потребуется способ, используя operator E
.Но это еще одно преобразование, определенное пользователем при инициализации, которое стандарт запрещает:
13.3.3.1/4
При вызове для копирования временного объекта на втором шаге класса copy-инициализация, [...], разрешены только стандартные последовательности преобразования и последовательности преобразования эллипса.
Вот почему ваш код не выполняется.