Различия между прямой инициализацией списков и инициализацией списков копий - PullRequest
0 голосов
/ 19 мая 2018

Я хотел бы знать, есть ли какая-либо разница в следующих двух типах инициализации std::vector в C ++ 11 и более поздних версиях.

std::vector<int> v1 {1, 2, 3, 4, 5};
std::vector<int> v2 = {1, 2, 3, 4, 5};

Вот полный пример кода, который отлично работает.

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v1 {1, 2, 3, 4, 5};
    std::vector<int> v2 = {1, 2, 3, 4, 5};

    std::cout << v1.size() << '\n';
    std::cout << v2.size() << '\n';
}

Я вижу, как обе инициализации приводят к одинаковым результатам.

В примере на http://en.cppreference.com/w/cpp/container/vector используется второй вид, так что я подумал, имеет ли этот тип инициализации какое-либо преимущество.

В общем, я хочу знать, имеет ли одна инициализация конкретное техническое преимущество перед другой, или считается, что одна инициализация считается оптимальной, а другая - нет, и если да, то почему.

Особенно меня беспокоит то, имеет ли инициализация копирования списка дополнительные издержки из-за временных объектов и копирования?

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Инициализация списка неофициально называется «равномерной инициализацией», потому что его значение и поведение должны быть одинаковыми независимо от того, как вы его вызываете.

Таким образом, существует именно и только одно различие между поведением прямой инициализации списка и инициализацией копирования списка: если инициализация списка вызовет конструктор, помеченный explicit, то возникает ошибка компиляции, если форма инициализации списка является копией-list инициализация.Это единственное отличие.

[dcl.list.init] объясняет синтаксическую разницу между прямым списком и списком копий.Таким образом, он описывает, какие формы инициализации списка являются прямыми против копирования.Но оно никогда не определяет функциональную разницу между ними.

Единственная часть стандарта, определяющая поведенческое различие, находится в [over.match.list] / 1 :

В copy-list-initialization, если выбран конструктор explicit, инициализация некорректна.

Это функция разрешения перегрузки.

Поскольку стандарт не определяет поведенческих различий, я был бывесьма удивительно, если компиляторы решили навязать им какую-то функциональную разницу.

0 голосов
/ 19 мая 2018

Я очень предпочитаю инициализацию списка копирования в целом (и особенно в случае std::vector), потому что инициализация прямого списка очень похожа на явные конструкторы std::vector, когда есть только один или два элемента.

std::vector<int> x(2);
// is very different from
std::vector<int> x{2};

Ясность в том, что я присваиваю начальное значение вектору, а не настраиваю его со значениями, меньше подвержена неправильному прочтению.

...