Почему конструктор std :: vector принимает список инициализаторов по копии? - PullRequest
3 голосов
/ 10 марта 2020

Когда я пытался понять различные типы инициализации в современном C ++, я столкнулся с инициализацией std::vector<T> со списком инициализации. Чтобы разрешить инициализацию с помощью структуры данных списка инициализаторов, такой как std::vector<T>, должен быть конструктор, который принимает инициализатор в качестве параметра. Я заметил, что std::vector<T> принимает список инициализаторов по копии, а не как ссылку, принятие по копии, когда у нас огромное количество элементов, может быть очень дорогим. Почему это так, есть ли какая-то особая причина, по которой список инициализаторов принимает его как копию вместо ссылки?

От https://en.cppreference.com/w/cpp/container/vector/vector

vector( std::initializer_list<T> init, … ); (9)     (since C++11)

Почему бы и нет ?

vector( std::initializer_list<T>& init, … );

Ответы [ 2 ]

5 голосов
/ 10 марта 2020

std::initializer_list не копирует базовые объекты.

Как вы можете читать здесь :

Копирование std::initializer_list не копирует базовый объект объекты.

Так что на самом деле это не тратит много памяти или времени.

3 голосов
/ 10 марта 2020

Согласно cppreference.com ,

Объект типа std::initializer_list<T> - это легкий прокси-объект, который обеспечивает доступ к массиву объектов типа const T.

Списки инициализаторов могут быть реализованы в виде пары указателей или указателя и длины. Копирование std::initializer_list не копирует базовые объекты.

Таким образом, несмотря на то, что std::initializer_list создает временный массив, элементы этого массива не копируются, даже если std::initializer_list передается по значению. Но, если хотите, вы можете принимать объекты этого типа по постоянной ссылке. Это прекрасно работает в моих проектах. Например:

auto some_function(const std::initializer_list<T>& list);
...