2014-12-10 2 views
0

이 코드 고려 붕괴 참조 : 난 아직도 앞으로 호출 할 필요가 왜C++ (11) 완벽한 전달 및

template<typename T> 
void foo(T&& param){ //In this case && is called universal reference 
    std:string tmp = std::forward<string>(param); 
} 

내 질문은 보편적 참조 유형 추론 할 수있는 경우를?
전달하지 않는 이유 T의 형식이 추론 된 경우에도 tmp의 올바른 c'tor가 호출되지 않습니다.

내 두 번째 질문은 참조 붕괴 규칙에 관한 것입니다 :

  1. A& &&A&
  2. A&& &&A&&

가되도록하게이 규칙에 따라 및 계정에서 보편적 인 기준을 복용하는 이유 표준 : 앞으로 서명 다음과 같을 수 없습니다 :

template<class T> 
T&& forward(T&& arg){ 
    return static_cast<T&&>(arg); 
} 

위의 규칙에 따라 T의 유형이 rvalue 참조 인 경우 r 값 참조로 축소됩니다. T 유형이 l 값 참조 인 경우 lvalue 참조로 축소됩니다.
그런데 std::forward에는 lvalue 참조와 rvalue 참조의 두 가지 다른 서명이 있는데 왜 내가 누락 되었습니까?

+3

요즘은 '전달 참조'라고합니다. –

+0

T $$ 란 무엇입니까? 그게 T &&라고 생각하니? – UpAndAdam

답변

2

보편적 인 참조 유형이 추론 될 수 있다면 내 질문에 왜 내가 앞으로 전화해야합니까?

때문에 즉시 매개 변수 param에 이름을 부여로있는 함수가를 rvalue로 호출, 그래서 그것을 사용하지 않는 한를 rvalue로 전달되지 않을 경우에도 좌변, forward<T>

전달하지 않는 이유 T의 형식이 추론 된 경우에도 tmp의 올바른 c'tor가 호출되지 않습니다.

param은 왼쪽 값입니다. foo에 전달 된 인수의 값 카테고리를 복원하려면 string& 또는 string&&으로 다시 캐스팅해야합니다. 즉, T의 유형을 알아야하고 캐스팅을 수행하는 데 forward을 사용해야 함을 의미합니다.

std::forward에는 lvalue 참조와 rvalue 참조의 두 가지 다른 서명이 있습니까?

그것은 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html

에 의해 변경되었습니다 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html의 배경 정보를 많이하고 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2951.html 있습니다

당신의 제안 버전에 대한 문제는 당신이 forward<string>을 말한다면 다음 매개 변수 T는 아무튼 그렇게 추론되지 않는 것입니다 '는 전달 참조로 작동합니다. 즉, T&&은 왼쪽 값에 바인딩 할 수 없으므로 param은 왼쪽 값이므로 forward<string>(param)이 작동하려면 왼쪽 값에 바인딩 할 수 있어야합니다.

+0

귀하의 대답에 따르면 foo의 param은 lvalue로 앞으로 전화를 걸 때 lvalue가되고 lvalue를 얻습니다. 그래서 여기에 rvalue 유형이 보존됩니까? Scott Meyers foo의 서명에 따르면 BTW는 param이 보편적 인 참조임을 의미합니다. –

+0

rvalue-ness는'foo'의 본문 내에서 손실됩니다. 왜냐하면'param'은 거기의 lvalue이므로 'forward'를 사용하여 rvalue 유형을 복원합니다. –

+0

그리고 이들은 현재 범용 참조가 아닌 [전달 참조] (http://isocpp.org/files/papers/N4164.pdf)라고합니다. –