2017-12-15 163 views
7
#include <array> 
using std::array; 

constexpr auto d1=2; 
constexpr auto d2=3; 
constexpr auto d3=4; 

// stacked std::array 
using arr_t = array<int,d1>; 
using arr2d_t = array<arr_t,d2>; 
using arr3d_t = array<arr2d_t,d3>; 
constexpr arr3d_t arr1 = {{ 
    {{ {1,2}, {3,4}, {5,6} }}, 
    {{ {1,2}, {3,4}, {5,6} }}, 
    {{ {1,2}, {3,4}, {5,6} }}, 
    {{ {1,2}, {3,4}, {5,6} }} 
}}; 

// built-in array 
using carr3d_t = int[d3][d2][d1]; 
constexpr carr3d_t arr2 = { 
    { {1,2}, {3,4}, {5,6} }, 
    { {1,2}, {3,4}, {5,6} }, 
    { {1,2}, {3,4}, {5,6} }, 
    { {1,2}, {3,4}, {5,6} } 
}; 

Chociaż można uciec całą działalność szelki tylko parę pojedynczych szelki takie jak:Dlaczego potrzebne są "podwójne nawiasy klamrowe" w deklaracji wielowymiarowej tablicy przy użyciu stosu std :: array?

// getaway with one-dimensional declaration 
constexpr arr3d_t arr3 = { 
    1,2, 3,4, 5,6, 
    1,2, 3,4, 5,6, 
    1,2, 3,4, 5,6, 
    1,2, 3,4, 5,6 
}; 
constexpr carr3d_t arr4 = { 
    1,2, 3,4, 5,6, 
    1,2, 3,4, 5,6, 
    1,2, 3,4, 5,6, 
    1,2, 3,4, 5,6 
}; 

Chciałbym wiedzieć, dlaczego {{ są wymagane z wyjątkiem najniższego wymiaru przy użyciu ułożone std ::szyk?

godbolt.org/g/b6qfn4

Odpowiedz

3

Twoje typy arr_t, arr2d_t, arr3d_t i carr3d_t są rodzaje kruszywa. Są to typy agregatów, ponieważ samo std::array jest typem zagregowanym. Ich obiekty są inicjowane za pomocą aggregate initialization, a podczas kompilacji z obsługą C++ 11 potrzebujesz (dodatkowych) klamr dookoła zagnieżdżonego inicjalizatora (inicjatorów). Począwszy od standardu C++ 14:

szelki wokół zagnieżdżonych list inicjator może być pomijana (pominąć)

+0

Próbuję obu clang i gcc, nie kompiluje. Oznacza to, że wszyscy nie wybierają C++ 14 brace elision dla przypadku std :: array? [godbolt.org/g/YWAbHo](https://gcc.godbolt.org/g/YWAbHo) – sandthorn

6

klamrami są aggregate initializer syntax i wewnętrzna są składni tablicy inicjatora.

C++ 14 umożliwia nawias klamrowy. Upewnij się, że kompilujesz z C++ 14 lub lepszym.