У меня есть несколько вопросов о способе присвоения значений массиву std :: - PullRequest
7 голосов
/ 01 июня 2019

Я изучаю C ++ на codesdope.com, и я прочитал документ на другом сайте, learncpp.com. Но эти два веб-сайта могут по-разному присваивать значения массиву.

//codesdope.com

std::array<int,5> n  {{1,2,3,4,5}};
//learncpp.com

std::array<int,5> n = {1,2,3,4,5};

Какой способ более точный? Какой путь мне выбрать? В чем разница между ними?

Ответы [ 3 ]

6 голосов
/ 01 июня 2019

Требуются двойные скобки в C ++ 11 до CWG 1270 (не требуется в C ++ 11 после ревизии и в C ++ 14 и более поздних версиях):

// construction uses aggregate initialization
std::array<int, 5> a{ {1, 2, 3, 4, 5} }; // double-braces required in C++11 prior to the CWG 1270 revision
std::array<int, 5> a{1, 2, 3, 4, 5}; // not needed in C++11 after the revision and in C++14 and beyond
std::array<int, 5> a = {1, 2, 3, 4, 5};  // never required after =

std :: ссылка на массив

1 голос
/ 01 июня 2019

Обе версии имеют одинаковый код сборки:

    std::array<int,5> n {{1,2,3,4,5}};

    mov     rcx, qword ptr [.L__const.main.n]
    mov     qword ptr [rbp - 24], rcx
    mov     rcx, qword ptr [.L__const.main.n+8]
    mov     qword ptr [rbp - 16], rcx
    mov     edx, dword ptr [.L__const.main.n+16]
    mov     dword ptr [rbp - 8], edx

второй стиль:

    std::array<int,5> n2 {1,2,3,4,5};

    mov     rcx, qword ptr [.L__const.main.n2]
    mov     qword ptr [rbp - 24], rcx
    mov     rcx, qword ptr [.L__const.main.n2+8]
    mov     qword ptr [rbp - 16], rcx
    mov     edx, dword ptr [.L__const.main.n2+16]
    mov     dword ptr [rbp - 8], edx

означает, что они оба имеют одинаковую производительность. Второе лучше, потому что оно более читабельно.

0 голосов
/ 12 июня 2019

std::array является агрегатным типом, тип является агрегатным типом, если он не имеет закрытых или защищенных прямых нестатических элементов данных, предоставленных пользователем конструктора, виртуальной функции и виртуальных, частных или защищенных базовых классов, например

struct S
{
  int arr[5];
};

Так что это может быть инициализировано как S s = { 0, 1, 2, 3, 4}; здесь элемент s.arr получить копию инициализации с помощью braced-init-list. Точно так же std::array также является агрегатным типом и все следующие различные синтаксисы,

std::array< int, 5> arr{ { 0, 1, 2, 3, 4}}; // double-braces required in C++11 prior to the CWG

std::array< int, 5> arr{ 0, 1, 2, 3, 4};
std::array< int, 5> arr = { 0, 1, 2, 3, 4};

запускает агрегатную инициализацию, и в них нет никакой разницы. Даже его можно инициализировать следующим образом

std::array< int, 5> arr = {};
std::array< int, 5> arr = { 0, 1, 2};

В случае пустого списка {} элементы arr должны быть инициализированы и иметь следующее значение [ 0, 0, 0, 0, 0], а в случае списка, содержащего меньше элементов { 0, 1, 2}, тогда первые 3 элемента arr должны быть инициализированы копией из braced-init-list и оставшихся элементов должно быть значение initialize, а конечное значение будет [ 0, 1, 2, 0, 0]

Пожалуйста, проверьте более подробную информацию на Совокупная инициализация

...