2017-01-13 1 views
5

나는 다음과 같은 한 템플릿 기능 :std :: initializer_list <int> ({1,2,3})과 {1,2,3}의 차이점은 무엇입니까?

template<typename T> void foo2(T t) {} 

내가 사용하여 호출 할 수 있다는 사실을 알고 : 초기화 목록 템플릿 인수에 대한 비 유추 상황이

foo2({1,2,3}); 

때문이다. 나는 사용해야합니다 :

foo2<std::initializer_list<int>>({1,2,3}); 

을하지만, 또한 사용할 수 있습니다 {1,2,3}std::initializer_list<int>({1,2,3}) :

foo2(std::initializer_list<int>({1,2,3})); 

날의 차이점은 무엇입니까 궁금하게하는?

+9

'std :: initializer_list ({1,2,3})'은'std :: initializer_list '형식의 표현식입니다. '{1,2,3}'은 표현이 아닙니다. 중괄호 목록은 표현식이 발생할 수있는 곳이 아닌 언어 정의가 명시 적으로 허용하는 컨텍스트에서만 발생할 수 있습니다. –

+2

@ M.M 답이 0 인 질문에 대한 대답을 알았지 만 의견에 답을 얻은 것으로 밝혀졌습니다. (͡ ° ʖ̯ ͡ °) – luk32

+2

@ luk32 답변을 쓰는 ​​것이 자유롭게 ... 전체 대답은 내가 확신하지 않는 템플릿의 세부 사항을 다루어야한다고 생각합니다 –

답변

7

braced-init list은 형식이 아니므로 유형이 없습니다. 당신이

foo2({1,2,3}); 

를 호출 할 때 컴파일러는 {1,2,3} 당신의 마음에 무엇을 나타내는 유형 모르는, 그래서 그것은 컴파일되지 않습니다. 여기에 컴파일러가 타입을 추론 할 필요가 없기 때문에

foo2<std::initializer_list<int>>({1,2,3}); 

컴파일, 당신이 그것을 지정한, 그것은 std::initializer_list<int>입니다. 따라서 t{1,2,3}으로 초기화 할 수 있습니다.

컴파일러가 형식을 추론 할 수 있기 때문에 세 번째 호출도 컴파일됩니다. std::initializer_list<int>({1,2,3})은 분명히 std::initializer_list<int>이므로 전달 된 prvalue로 t을 초기화 할 수 있습니다.

+2

C++ 17에서는 "elution 보장"규칙을 통해 마지막 단락을 다르게 지정할 수 있습니다. 어떤 의미에서 더 이상 거기서 생성 된 값이 없으며 함수 인수로 생략됩니다. 함수 인수를 초기화하는 방법이됩니다. 또는 나는 모여서 새로운 규칙을 아직 익히지 못했다. (실제로이 경우 차이가 없다) – Yakk

관련 문제