2016-06-09 5 views
-1

는 [현대 효과적인 C는 ++] 말한다 : 템플릿 인스턴스화, T의 종류를 알고해야 할 때, 여기있는 동안 {1,2,3}이 보강-초기화 목록을하기 때문에반환 값을 추론 할 때 "auto"가 braced-init-list를 허용하지 않는 이유는 무엇입니까?

template<class T> 
void f(T t){} 
int main(){ 
    f({1,2,3}); 
} 

는, 컴파일을 실패합니다. 다음 내 질문에 내가 이것을 이해할 수

auto x={1,2,3};//auto deduces x to std::initializer_list 
f(x); 

만 : 같은 해결해야 책이 반환 값 공제 "자동"을 사용할 때, 말을 계속하는 이유

을, 그것을 받아 보강-초기화를 추론 할 수 없습니다 -명부?

auto f() 
{ 
    return {1,2,3}; 
} 

컴파일에 실패합니다.

이 C++ 14 표준의 일부인 경우이 같은 제한의 그리고 말을 계속하는 이유 Emmmmm는 이해가 안 돼요? "NEWVALUE"전에

auto resetV=[&v](const auto& newValue){v=new Value;} 

"자동"을 할 수 없습니다 {1,2,3}도 수락하십시오. 왜 우리는 그런 2 가지 제한이 있습니까?

어쩌면 언어 디자인 관점에서 생각해 보면 형식 공제를 수행 할 때 약간의 혼란이있을 것입니다. 그냥 추측. 이러한 디자인 결정의 단서가 있습니까? 며칠 동안 나를 혼란스럽게 만들었습니다.

감사합니다.

답변

2

std::initializer_list은 익명 어레이에 대한 참조입니다.

배열 자체는 initializer_list이 작성된 블록 범위에 있습니다. 어레이의 수명 f의 본체이며,이 코드를 거의 완전하게 분리 된 구간에 존재하는 참조하는 initializer_list 때문에

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

거의 완전히 쓸모.

initializer_list을 사용하는 것은 거의 확실하게 정의되지 않은 동작입니다. 당신은 아마도 그 크기를 물어 볼 수 있고 그것이 비어 있다면 그것은 정의 된 행동 일 수도 있습니다 (잘 모르겠지만 검사 할만큼 신경 쓰지는 않습니다). 그러나 그 내용을 조사 할 수는 없습니다.

초기화 목록은 데이터에 대한 참조이며 데이터 사본은 아닙니다.경우

:

auto f() { 
    return {1,2,3}; 
} 

위의 수 자체를 추론, 거의 결코 도움이 될 것입니다.

auto x = {1,2,3};의 예외는 initailizer_list<int>{} 집합에서 추론 될 수있는 유일한 경우입니다. (C++ 11에서는 auto x{1};도 마찬가지 였지만 무시되었습니다).

1

왜 책이 계속해서 말하는가? 반환 값 공제에 "auto"를 사용하면 braced-init-list를 수락하고 추론 할 수 없습니까?

"그것을 추론 할 수 없다"는 것이 아닙니다. 그것은 허용되지 않습니다. 이 코드에 대해 신중히 생각하십시오.

#include <initializer_list> 

auto f() -> std::initializer_list<int> 
{ 
    return {1,2,3}; 
} 

컴파일됩니까? 예. 안전 해요? 아니요. 잠재적으로 기본 배열의 수명과 관련하여 모든 종류의 문제가 발생할 수 있습니다. std::initializer_list은 컨테이너처럼 사용하면 안됩니다.

+0

"잠재적으로"뿐만 아니라. 그 배열은 당신이 함수를 빠져 나가 자마자 전 배열이다. –

+0

반환 유형은 initializer_list 객체의 복사본입니다. 그렇다면 왜 이것이 사전 배열입니까? 감사 –