Как имитировать поведение инициализации массива C «int arr [] = {e1, e2, e3,…}» с помощью std :: array?

(Примечание: этот вопрос касается того, что не нужно указывать количество элементов и при этом разрешать непосредственную инициализацию вложенных типов.)
В этом вопросе обсуждается оставшееся использование массива C, например int arr [20]; . В своем ответе @James Kanze показывает одну из последних цитаделей массивов C, ее уникальные характеристики инициализации:

int arr[] = { 1, 3, 3, 7, 0, 4, 2, 0, 3, 1, 4, 1, 5, 9 };

Нам не нужно указывать количество элементов, ура! Теперь переберите его с помощью функций C ++ 11 std :: begin и std :: end из ( или ваших собственных вариантов ), и вам даже не нужно думать о его размере.

Теперь, есть ли какие-нибудь (возможно, TMP) способы добиться того же с помощью std :: массив ? Использование макросов позволило сделать его красивее. :)

??? std_array = { "here", "be", "elements" };

Правка : Промежуточная версия, составленная из различных ответов, выглядит так:

#include 
#include 

template::type>
std::array make_array(T&& head, Tail&&... values)
{
  return { std::forward(head), std::forward(values)... };
}

// in code
auto std_array = make_array(1,2,3,4,5);

И использует все виды классных вещей C ++ 11:

  • Вариативные шаблоны
  • sizeof ...
  • rvalue ссылки
  • идеальная пересылка
  • std :: array , конечно
  • равномерная инициализация
  • без возврата типа с универсальной инициализацией
  • вывод типа ( auto )

И пример можно найти здесь .

Однако , как @Johannes указывает в комментарии к ответу @ Xaade, вы не можете инициализировать вложенные типы с такой функцией . Пример:

struct A{ int a; int b; };

// C syntax
A arr[] = { {1,2}, {3,4} };
// using std::array
??? std_array = { {1,2}, {3,4} };

Кроме того, количество инициализаторов ограничено количеством аргументов функции и шаблона, поддерживаемых реализацией.

133
задан Community 23 May 2017 в 11:54
поделиться