Почему нужны копии при инициализации std::vector с помощью std::initializer_list?

Рейтинг: 0Ответов: 1Опубликовано: 15.04.2023
#include <initializer_list>
#include <memory>
#include <vector>

struct S {
    S() = default;
    S(const S&) = delete;
};

struct A {
  A(std::initializer_list<std::unique_ptr<S>>);
} a{std::make_unique<S>()};           // 1

std::vector v{std::make_unique<S>()}; // 2

Почему я могу сделать 1, но не могу 2? Читал, что это из-за того, что initializer list создаёт копии, т.к. не может сделать move из const T массива. Но ведь тогда и первый пример бы не работал.

Ответы

▲ 1Принят

Но ведь тогда и первый пример бы не работал.

А там нет попытки move из константного массива. Константность массива не мешает перемещать в него. (Но в вашем случае даже перемещения не происходит, элемент создается сразу в массиве благодаря mandatory copy elision.)

Сделал небольшую библиотеку better_list_init, которая это обходит: запустить

#include <better_list_init.hpp>

#include <memory>
#include <vector>

struct S {
    S() = default;
    S(const S&) = delete;
};

std::vector<std::unique_ptr<S>> v = init{std::make_unique<S>()};
//                                  ^~~~