2012-05-15 3 views
4
#include <iostream> 

class Foo { }; 

Foo createFoo() { return Foo(); } 

void bar(Foo &&) { std::cout << "in bar(Foo &&)\n"; } 

void bar(Foo const &) { std::cout << "in bar(Foo const &)\n"; } 

void baz(Foo &&f) { 
    std::cout << "in baz, "; 
    bar(f); 
    // bar(std::move(f)); 
} 

int main() 
{ 
    baz(createFoo()); 
    return 0; 
} 

내 예상 출력은 in baz, in bar(Foo &&)이지만, 나는 받고 있습니다 : in baz, in bar(Foo const &). 전화를 bar (의견보기)로 전환하면 예상되는 결과를 얻지 만 이는 나에게 잘못된 것으로 보입니다. 컴파일러가 Foo&&Foo&&으로 변환하지 않고 bar(Foo &&)을 호출 할 수없는 이유가 있습니까?r 값 참조에 대한 혼란

미리 감사드립니다.

+5

'Foo && f '의'f'는 이름이 지정되어 있으므로 lvalue이므로 rvalue 참조에 직접 바인딩하지 않습니다. – ildjarn

답변

13

인사이드 baz(Foo&& f), f1value입니다. 따라서 우세 참조로 bar에 전달하려면 우위 값으로 캐스팅해야합니다. static_cast<Foo&&>(f) 또는 std::move(f)으로이 작업을 수행 할 수 있습니다.

예를 들어 같은 기능에서 우연히 여러 번 움직이는 것을 방지 할 수 있습니다. bar(f) 번을 baz 번으로 여러 번 호출했습니다.

+3

'static_cast'로 _not_하십시오! – leftaroundabout

+0

@leftaroundabout : 왜 'static_cast'가 아니겠습니까? 분명히'std :: move'는 읽기에 더 깨끗하고 항상 작동 할 것이지만'static_cast'는 좋지 않을 것입니다. –

+1

@Stephen Newell'static_cast'는 명확하게 의도를 표현하지 않아서 독자를 오해의 소지가있게 만들 수도 있습니다. 예를 들어'&'를'&&'로 잘못 입력했다고 생각하게 만들 수 있습니다. –

4

간단히 말해, 명명 된 우변 값 참조는 좌변 값입니다. 이는 나중에 사용해야하는 명명 된 변수에서 자동으로 빠져 나오는 것을 방지하기위한 것입니다. 반대로 명명되지 않은 임시 저장은 다시 사용될 수 없으므로 자동으로 이동할 수 있습니다.

나는이 시리즈를 발견했다. http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ 조금 오래 되더라도 꽤 도움이된다.