std :: array의 기본 초기화?


104

C ++ 11 std::array을 사용하면 구문 std::array<T, N> x;이 배열의 모든 요소를 ​​기본값으로 초기화 한다는 보장이 있습니까?

편집 : 그렇지 않은 경우 모든 요소를 ​​기본값으로 초기화하기 위해 모든 배열 (0 크기 배열 포함)에서 작동하는 구문이 있습니까?

편집 : cppreference 에서 기본 생성자 설명은 다음과 같습니다.

(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array 

그래서 대답은 '예'일 수 있습니다. 그러나 나는 표준 또는 미래 표준에 따라 그것을 확신하고 싶습니다.


그렇게 생각하지 마십시오. 기본적으로 선언되어 있으므로 기본적으로 T x[N]구문 과 동일 합니다.
Rapptz 2013-08-18

답변:


149

정의에 따라 기본 초기화는 다른 초기화가 지정되지 않은 경우 발생하는 초기화입니다. C ++ 언어 는 명시 적 이니셜 라이저를 제공하지 않은 모든 개체가 기본적으로 초기화 됨을 보장합니다 (C ++ 11 §8.5 / 11). 여기에는 std::array<T, N>및 유형의 개체가 포함됩니다 T[N].

기본 초기화가 효과가없고 개체의 값을 결정되지 않은 상태로 두는 유형 (클래스가 아닌 배열 유형 (§8.5 / 6))이 있습니다. 결과적으로 이러한 유형을 가진 기본 초기화 된 객체 배열은 불확실한 값을 갖게됩니다. 예 :

int plain_int;
int c_style_array[13];
std::array<int, 13> cxx_style_array;

c 스타일 배열과 std::array모두 불확정 값이있는 것처럼 불확정 값의 정수로 채워 plain_int집니다.

모든 요소를 ​​기본값으로 초기화하기 위해 모든 배열 (크기가 0 인 배열 포함)에서 작동하는 구문이 있습니까?

"기본값으로"라고 말하면 "모든 요소를 T{}"로 초기화 "한다는 뜻 입니다. 그것은 default-initialization 이 아니라 value-initialization (8.5 / 7)입니다. 각 선언에 빈 이니셜 라이저를 제공하여 C ++ 11에서 값 초기화를 매우 쉽게 요청할 수 있습니다.

int plain_int{};
int c_style_array[13]{};
std::array<int, 13> cxx_style_array{};

차례로 모든 배열 요소의 값을 초기화하여 plain_old_int, 두 종류의 배열의 모든 구성원이 0으로 초기화됩니다.


클래스 멤버라면 어떨까요 : struct X {std :: array <int, 12> dozen; X () : dozen () {} 그러면 12 개의 0이 나옵니까?
gerardw

4
@gerardw 표준에 따르면 그렇습니다. MSVC의 버그를 조심하십시오. 일부 경우 값 초기화를 올바르게 구현하지 못합니다.
Casey

1
실제로 부스트는 그렇게 말하고 boost::value_initialized 링크로 해결 하지만 VC12 (VS2013)가 훨씬 더 나은 지원을 제공한다고 생각합니다.
v.oddou

1
위원회가 표준을 기본값 초기화로 변경하고 요청에 따라 가치를 훼손하기를 바랍니다. 즉 std :: array <int, 12> = {std :: undetermined}; 또는 뭔가
빅토르 SEHR

실제로 무언가를 불확실한 값으로 초기화한다는 것은 무엇을 의미합니까? 대안은 무엇입니까?
Andrew

21

Default-initialization 은 잠재적 으로 초기화 가 전혀 없음을 의미하는 Standard의 용어이므로 아마도 zero-initialization을 의미 할 것입니다 .

cppreference.com의 설명은 실제로 약간 오해의 소지가 있습니다. std::array집합 클래스이고 요소 유형이 기본형이면 POD : "일반 오래된 데이터"이며 의미 체계는 C 언어와 거의 일치합니다. 의 암시 적 정의 생성자는 std::array< int, N >A는 사소한 절대적으로 아무것도하지 않는 한.

구문처럼 std::array< int, 3 >()또는 std::array< int, 3 > x{}어떤 제로화 값이 생성자를 호출하여 그렇게하지 않습니다 제공합니다. 0을 얻는 것은 C ++ 11 §8.5 / 8에 지정된 value-initialization의 일부입니다 .

T 유형의 객체를 값 초기화한다는 것은 다음을 의미합니다.

— T가 사용자가 제공하거나 삭제 된 기본 생성자가없는 (가능하게는 cv-qualified) 클래스 유형이면 객체는 0으로 초기화되고… T에 사소하지 않은 기본 생성자가 있으면 객체는 기본으로 초기화됩니다.

std::array사용자가 제공 한 기본 생성자가 없으므로 0으로 초기화됩니다. 묵시적으로 정의 된 기본 생성자가 있지만 사소하기 때문에 기본적으로 초기화되지 않습니다. (그러나 정의에 의한 사소한 초기화는 런타임에 영향을 미치지 않기 때문에 차이가 없습니다.)

그렇지 않은 경우 모든 요소를 ​​기본값으로 초기화하기 위해 모든 배열 (크기가 0 인 배열 포함)에서 작동하는 구문이 있습니까?

C 스타일 배열이며 std::array둘 다 집계이며 집계를 완전히 0으로 초기화하는 방법은 구문을 사용하는 것 = {}입니다. 이것은 C ++ 98부터 작동합니다. C 스타일 배열은 0 범위를 가질 수 없으며 0 sizeof (std::array< X, 0 >)이 아닙니다.


6

모두 T x[N];std::array<T, N> x;배열의 모든 요소를 기본 초기화.

예를 들어이면 T = std::string모든 요소는 빈 문자열이됩니다. T기본 생성자가없는 클래스 인 경우 둘 다 컴파일에 실패합니다. 이면 T = int모든 요소가 불확실한 값을 갖게됩니다 (해당 선언이 네임 스페이스 범위에 있지 않는 한).


0

우선, T x [N]은 기본적으로 요소를 초기화하지만, 스칼라 유형 T의 기본 초기화는 실제로 아무 작업도 수행하지 않습니다. 위의 내용은 std :: array x에도 적용됩니다. 필요한 것은 목록 초기화라고 생각합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.