LINUX.ORG.RU

История изменений

Исправление Kuzy, (текущая версия) :

Проблема в том, что у std::initializer_list нет move-конструктора.

У него есть move-конструктор. Но std:begin и std::end для него возвращают константный указатель, а данные по константному указателю нельзя move-ать.

auto l = {1, 2, 3};
int&& num = std::move(*l.begin()); // error

Вместо него компилятор пытается использовать copy-конструктор, а его нет у std::unique_ptr

auto l = {
    std::unique_ptr<Base> {new Base {10}},
    std::unique_ptr<Base> {new A {}},
    std::unique_ptr<Base> {new B {'x'}},
};
std::vector<unique_ptr<Base>> v {std::move(l)}; // error

Не могу придумать ничего лучше этого:

std::vector<unique_ptr<Base>> v; 
v.push_back(std::unique_ptr<Base> {new Base {10}});
v.push_back(std::unique_ptr<Base> {new A {}});
v.push_back(std::unique_ptr<Base> {new B {10}});

Если сильно хочется сделать вектор константным, то можно так:

const std::vector<unique_ptr<Base>> v = [] () {
    std::vector<unique_ptr<Base>> result;
    result.push_back(std::unique_ptr<Base> {new Base {10}});
    result.push_back(std::unique_ptr<Base> {new A {}});
    result.push_back(std::unique_ptr<Base> {new B {10}});
    return result;
} ();

Ничего не поделаешь, это std::initializer_list.

Исходная версия Kuzy, :

Проблема в том, что у std::initializer_list нет move-конструктора.

У него есть move-конструктор. Но std:begin и std::end для него возвращают константный указатель, а данные по константному указателю нельзя move-ать.

auto l = {1, 2, 3};
int&& num = std::move(*l.begin());

Вместо него компилятор пытается использовать copy-конструктор, а его нет у std::unique_ptr

auto l = {
    std::unique_ptr<Base> {new Base {10}},
    std::unique_ptr<Base> {new A {}},
    std::unique_ptr<Base> {new B {'x'}},
};
std::vector<unique_ptr<Base>> v {std::move(l)}; // error

Не могу придумать ничего лучше этого:

std::vector<unique_ptr<Base>> v; 
v.push_back(std::unique_ptr<Base> {new Base {10}});
v.push_back(std::unique_ptr<Base> {new A {}});
v.push_back(std::unique_ptr<Base> {new B {10}});

Если сильно хочется сделать вектор константным, то можно так:

const std::vector<unique_ptr<Base>> v = [] () {
    std::vector<unique_ptr<Base>> result;
    result.push_back(std::unique_ptr<Base> {new Base {10}});
    result.push_back(std::unique_ptr<Base> {new A {}});
    result.push_back(std::unique_ptr<Base> {new B {10}});
    return result;
} ();

Ничего не поделаешь, это std::initializer_list.