(Примечание. Этот вопрос связан с необходимостью не указывать количество элементов и разрешать прямую инициализацию вложенных типов.)
В этом вопросе обсуждается использование слева для массива C, например int arr[20];
. На его ответ, @James Kanze показывает один из последних оплотов массивов C, это уникальные характеристики инициализации:
int arr[] = { 1, 3, 3, 7, 0, 4, 2, 0, 3, 1, 4, 1, 5, 9 };
Нам не нужно указывать количество элементов, ура! Теперь перебираем его с помощью функций С++ 11 std::begin
и std::end
из <iterator>
(или ваших собственных вариантов), и вам никогда не нужно даже думать о его размер.
Теперь, есть ли какие-либо (возможно, TMP) способы достичь того же с помощью std::array
? Использование макросов позволило сделать его более приятным.:)
??? std_array = { "here", "be", "elements" };
Изменить. Промежуточная версия, скомпилированная из различных ответов, выглядит следующим образом:
#include <array>
#include <utility>
template<class T, class... Tail, class Elem = typename std::decay<T>::type>
std::array<Elem,1+sizeof...(Tail)> make_array(T&& head, Tail&&... values)
{
return { std::forward<T>(head), std::forward<Tail>(values)... };
}
// in code
auto std_array = make_array(1,2,3,4,5);
И использует все классные С++ 11 вещи:
- Шаблоны Variadic
-
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} };
Кроме того, количество инициализаторов ограничено количеством аргументов функции и шаблона, поддерживаемых реализацией.