2014-12-18 5 views
3

***에 의해 주석 처리 된 행에서 Bar의 복사 생성자가 호출되는 이유는 무엇입니까? input_bar은 rvalue 참조이므로 이동 생성자가 호출되기를 기대합니다. lvalue 참조로 변환 되었습니까? 해당 행을 bar_(std::move(input_bar))으로 변경하면 이동 생성자 호출을 만들 수 있습니다.이동 생성자 구현

#include <iostream> 
#include <array> 
#include <memory> 

class Bar 
{ 
public: 
    Bar(const Bar& bar) 
    { 
    std::cout << "copy constructor called" << std::endl; 
    } 

    Bar(Bar&& bar) 
    { 
    std::cout << "move constructor called" << std::endl; 
    } 
}; 

class Foo 
{ 
public: 
    Foo(Bar&& input_bar) : 
    bar_(input_bar) // *** 
    { 
    } 
    Bar bar_; 
}; 

int main() 
{ 
    Bar bar; 
    Foo foo(std::move(bar)); 
    return 0; 
} 
+0

참조 http://stackoverflow.com/q/27554296/981959 –

답변

8

엔티티에 이름이 있으면 분명히 lvalue입니다. 원 값 참조에 대한 이름이있는 경우 이름이 이 아니고은 아니며 왼쪽 값이지만 왼쪽 값입니다. 요점은이 엔티티가 rvalue를 참조하고 합법적으로 내용을 이동할 수 있다는 것을 알고 있다는 것입니다. 당신은 당신이 전화를 다음 함수에 rvalueness를 전달하려는 경우

, 당신은를 rvalue는 생성자가 소유 한 것으로 간주됩니다 std::move()없이, 예컨대 :

Foo(Bar&& bar): bar_(std::move(bar)) {} 

std::move()을 사용하십시오. std::move()으로 소유권을 해제하고 다음 기능으로 전달합니다.

+0

표준 참조는 필수적이지는 않지만 _nice_입니다. –

+0

알겠습니다. 내가 이해하는 데 도움이되는 것은 rvalue 참조 (즉,'input_bar')는 rvalue에 대한 참조이므로 lvalue입니다. 나는 그것이 명백하게 들리는 것을 안다. .. –

2

당신은 rhrs를 이동해야 :

Foo(Bar&& input_bar) : 
    bar_(std::move(input_bar)) // *** 
    { 
    } 

추론은 우리가 실제로 RHR를 사용하면, 그것은 semantially 범위 밖으로으로 처리해야한다는 것입니다. std::move를 사용하도록 강제하는 것은 다음과 같은 코드가 정의되지되지 않을 수 있습니다 :

엄지 손가락의 일반적인 규칙은 이름이없는 유일한 일이 실제로 RHR의로 사용할 수 있다는 것입니다
Foo(Bar&& input_bar) { 
    std::cout << input_bar.baz << std::endl;//not undefined 
    bar_ = Bar{std::move(input_bar)};//input_bar is now essentailly destroyted 
    //std::cout << input_bar.baz << std::endl;//Undefined behavior, don't do this 
} 

... 인수가 이름을 가지고 RHR, 따라서 것이다 당신이 그 (것)들에 기능을 부를까지 LHR로 대우하십시오.

+0

예, OP가 이미이 답변없이 발견되었으므로. OP가 왜 그것이 필요한지, 왜 'std :: move'가 사용되지 않는 한 그 효과가 달성되지 않는지에 대한 설명을 요구하고 있습니다. – hvd

+0

@hvd oo ok는 – IdeaHat

+0

을 편집 할 것입니다. 마지막 행이 정의되지 않은 동작을 생성하는지 여부는'baz'가 무엇인지에 따라 다릅니다. 대부분의 유형에서는 정의되지 않은 동작이 될 것이라고 기대하지 않습니다. –