A std::unique_ptr<base>
отличается от типа std::unique_ptr<derived>
. Когда вы делаете
test t(std::move(pd));
Вы вызываете конструктор преобразования std::unique_ptr<base>
для преобразования pd
в std::unique_ptr<base>
. Это нормально, поскольку вам разрешено преобразование, определенное одним пользователем.
В
test t = std::move(pd);
Вы выполняете инициализацию копирования, поэтому вам необходимо преобразовать pd
в test
. Это требует 2 пользовательских преобразований, и вы не можете этого сделать. Сначала вам нужно конвертировать pd
в std::unique_ptr<base>
, а затем вам нужно конвертировать его в test
. Это не очень интуитивно понятно, но когда у вас есть
type name = something;
независимо от того, something
должно быть только одно преобразование, определенное пользователем из типа источника В вашем случае это означает, что вам нужно
test t = test{std::move(pd)};
, который использует только одного неявного пользователя, определенного как первый случай.
Давайте удалим std::unique_ptr
и рассмотрим в общем случае. Поскольку std::unique_ptr<base>
не совпадает с типом std::unique_ptr<derived>
, у нас по существу есть
struct bar {};
struct foo
{
foo(bar) {}
};
struct test
{
test(foo){}
};
int main()
{
test t = bar{};
}
и мы получаем одну и ту же ошибку , потому что нам нужно перейти от bar -> foo -> test
, и для одного преобразования, определенного пользователем, слишком много.