41

초기화 할 std::array이 있다고 가정합니다.std :: array 초기화 중괄호 elish

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

브레이스 생략 누락 된 괄호 처리됩니다로서 그것은 또한 좋은 오래된 집계 초기화에 하나의 중괄호를 사용하는 것이 괜찮습니다 :

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

을 그러나이있다 이중 중괄호를 사용하는 경우 괜찮아 하나의 중괄호를 사용하여 목록 초기화를 사용할 수 있습니까? GCC는이를 받아들입니다. Clang은 "직접 목록 초기화를 사용할 때 하위 객체 초기화를 중심으로 중괄호를 생략 할 수 없습니다"라는 이유로 거부합니다.

모든 암시 적 형식 변환 (제 4 항)이 고려 집계 멤버를 초기화 할 때 :

std::array<int, 2> x{0, 1}; 

중괄호 생략 언급되는 표준의 유일한 부분은 말한다 8.5.1/12입니다 할당 표현식. 할당 표현식이 멤버를 초기화 할 수 있으면 멤버가 초기화됩니다. 그렇지 않고 구성원 자체가 하위 집합 인 경우 중괄호가 사용되며 하위 집합의 첫 번째 구성원이 초기화 될 때 대입 표현식이 고려됩니다.

8.5.1은 구체적으로 집약 초기화에 관한 것이므로 Clang이 거부하는 것이 맞습니까? 그리 빠르지는 않습니다. 8.5.4/3 메시지 : 다음 객체 또는 타입 T의 기준

리스트 초기화 정의된다

[...]

- 그렇지 않으면, T는 집합 인 경우, 집합체 초기화가 수행됩니다 (8.5.1).

나는 그것이 중괄호 elision을 포함하여 집계 초기화와 동일한 규칙이 적용된다는 것을 의미한다고 생각한다. GCC는 받아 들일만한 의미이다.

나는이 문구가 특별히 명확하지 않다는 것을 인정한다. 그래서, 어떤 컴파일러가 세 번째 스 니펫을 다루는 데 맞습니까? 중괄호 엘림은 목록 초기화에서 발생합니까 아니면 그렇지 않은 것입니까?

+0

좋은 질문! 어떤 표준을 사용하는지 언급 할 가치가 있습니다. C++ 11 표준 또는 그렇지 않은 경우 어떤 특정 초안. – juanchopanza

+0

"할당과 같은 초기화"를 복사 초기화라고합니다. 할당 생성자가 아니라 복사 생성자를 호출합니다. – TemplateRex

+0

@TemplateRex : 그래서 "좋아요"라는 작품을 사용했습니다. – Fanael

답변

20

Brace elision이 적용되지만 C++ 11에는 적용되지 않습니다. C++ 14에서는 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1270 때문에 적용됩니다. 운이 좋으면 Clang이 C++ 11 모드로 백 포트합니다.

+0

현재, archlinux의'clang-5.0'은 여전히'-std = C++ 17 '을 사용하는 중괄호 elision을 지원하지 않습니다. –

3

관련 : 짧은에서 http://en.cppreference.com/w/cpp/language/aggregate_initialization

,

struct S { 
    int x; 
    struct Foo { 
     int i; 
     int j; 
     int a[3]; 
    } b; 
}; 
S s1 = { 1, { 2, 3, {4, 5, 6} } }; 
S s2 = { 1, 2, 3, 4, 5, 6}; // same, but with brace elision 
S s3{1, {2, 3, {4, 5, 6} } }; // same, using direct-list-initialization syntax 
S s4{1, 2, 3, 4, 5, 6}; // error in C++11: brace-elision only allowed with equals sign 
         // okay in C++14 
관련 문제