이유는 많다 :
대회. 다음 코드를 고려하십시오 : 당신이 그 코드를 볼 경우
Foo foo;
Foo bar(std::move(foo));
, 그것은 이다 풍부 당신이 뭘 하려는지 명확 : 당신이 bar
에 foo
이동하고 있습니다. 대조적으로 :
이것은 무엇을 의미합니까? 다른 Foo
에 대한 포인터를 저장하고 있습니까? Foo
어떤 종류의 연결된 목록 노드 유형입니까? 당신은 Foo
의 포인터 기반 생성자에 대한 설명서에서 찾아야 할 것입니다.
prvalues에 대한 포인터를 가져올 수 없습니다. Foo bar(Foo{})
(pre-C++ 17)은 임시로 prvalue를 생성 한 다음 bar
으로 이동할 수 있습니다 (이동은 pre-C++ 17에서 생략 할 수 있습니다). 그러나 당신은 이것을 할 수 없습니다 : Foo bar(&Foo{})
.
의미가있는 것으로부터 자동으로 이동합니다. C++ 17의 일반화 생략이 자동 이동의 대부분은 멀리 갈 수 있지만, 남아 몇 가지가있다 :이 std::move
를 호출 할 필요없이 foo
에서 이동합니다
Foo function()
{
Foo foo;
//Do stuff
return foo;
}
. 그 이유는 foo
이 파괴 될 지역 변수이기 때문입니다. 이 방법으로 반환하면 반환 값으로 옮기는 것이 매우 합리적이라는 것을 의미합니다.
길을 명시 적으로 작성하려면 return &foo
이 필요합니다. 그리고 그것은 auto
반환 유형 공제로 일을 다소 어렵게 만듭니다. 이러한 함수는 Foo*
을 추론합니다. 즉, 방금 포인터가 매달려있는 것을 반환합니다. 반면에 return foo;
을 수행하면 Foo
prvalue가 자동 이동 (생략 될 수 있음)으로 추정됩니다.
nullptr
검사 필요 없음. Foo*
을 사용하면 누군가가 null 포인터를 전달할 가능성이 있습니다. 참조가있는 반면, 그것은 훨씬 더 어려울 것입니다 (그리고 그들은 이미 UB를 호출했을 것입니다). 우리는 기존의 언어 구조와 지원을 이동하고자한다면
, 우리는 그냥 "이동"이 아닌 포인터를 의미하는 비 const
참조를 사용했을 것입니다. 자체 구문을 제공함으로써, 우리가 무언가를 움직이고있을 때와 그렇지 않을 때를 분명히합니다.
글쎄요, 처음에는 rvalue의 주소를 가져올 수 없습니다. – Brian
장점은 해당 이동/복사 컨텍스트에서 이동 생성자가 자동으로 사용된다는 것입니다. 귀하의 "포인터"생성자되지 않습니다. – AnT
또한 참조는 null이 될 수 없지만 포인터가 될 수 있으므로 스와핑 전에 해당 조건을 명시 적으로 확인해야합니다. –