2013-06-15 2 views
3

왼쪽 값이 rvalue 참조에 바인딩되는 방식을 이해하려고합니다.왼쪽 값이 rvalue 참조에

#include <iostream> 

template<typename T> 
void f(T&& x) { 
    std::cout << x; 
} 

void g(int&& x) { 
    std::cout << x; 
} 

int main() { 
    int x = 4; 
    f(x); 
    g(x); 
    return 0; 
} 

f()를 호출하는 동안 g()를 호출하면 컴파일 타임 오류가 발생합니다. 이런 종류의 바인딩은 템플릿에서만 작동합니까? 왜? 우리는 어떻게 든 템플릿없이 그것을 할 수 있습니까?

답변

6

은 템플릿 인수이므로 T&&전달 참조이됩니다. 참조 축소 규칙으로 인해 f(T& &&)은 0 값의 경우 f(T&)이되고, 값의 경우 f(T &&)f(T&&)이됩니다.

+0

그건 의미가 있습니다. 그러나 템플릿이 필요 없다고 가정하면 위의 예에서 범용 참조를 얻을 수있는 방법이 있습니까? 나는 이것을 위해 약간의 질문을 편집했다. –

+0

@ r.v lvalues ​​('void g (int &)')에 대해'g'의 두 번째 오버로드를 제공하거나'std :: move'로 lvalues를 * 이동할 수 있습니다. – 0x499602D2

+0

그래, 가능한 해결책이지만 우리는 보편적 인 참조 라인에서 뭔가를 얻을 수 있었으면 좋겠다 : 유형 T (고정식, 템플릿이 아닌)가 주어지면 하나의 호출 (오버로드 없음)에서 T &와 T &&를 모두 일치시킬 수 있고 전달 , 등등. 그것은 확실히 일부 중복 코드를 줄이는 데 도움이됩니다. –

0

0x499602D2 님이 이미 질문에 답변했습니다.; 그럼에도 불구하고 코드를 다음과 같이 변경하면 더 많은 통찰력을 얻을 수 있습니다.

은 내가 추론 유형을 확인하기 위해 static_assertf에 추가 한 :

#include <type_traits> 

template<typename T> 
void f(T&& x) { 
    static_assert(std::is_same<T&&, int&>::value,""); 
    std::cout << x; 
} 

어설가 하지이 실패 않기 때문에 f에서 x의 유형 (이 특정 예에서) 결국 int&입니다. gmain에라고 어떻게 변경

:

g(std::move(x)); 

이제 코드를 컴파일하고 예상 인쇄 44으로 프로그램이 작동합니다.

희망 사항은 rvalue 참조를 이해하는 데 도움이되기를 바랍니다.

+1

템플릿이 이미 있습니다. ['std :: is_rvalue_reference'] (http : // en.cppreference.com/w/cpp/types/is_rvalue_reference) – 0x499602D2

관련 문제