2011-05-15 3 views
22

다음 함수를 고려하십시오.값으로 반환 될 때 값 매개 변수가 암시 적으로 이동됩니까?

Foo foo(Foo x) 
{ 
    return x; 
} 

return x이 복사 생성자 또는 이동 생성자를 호출합니까?

조사할만한 이동 가능하지만 복사 할 수없는 간단한 Foo 클래스를 작성했습니다.

struct Foo 
{ 
    Foo() = default; 
    Foo(const Foo&) = delete; 
    Foo(Foo&&) = default; 
}; 

값 매개 변수를 값으로 반환 할 때 이동 생성자가 호출 된 경우 all 괜찮을거야. 그러나 현재 g ++ 컴파일러는 return x에 대해 다음과 같은 오류 메시지를 표시합니다.

error: deleted function 'Foo::Foo(const Foo&)' 

return xreturn std::move(x)로 바꾸면 모든 것이 정상입니다. 이것으로부터 필자는 원하는 경우 값 매개 변수에서의 이동이 명시 적으로 수행되어야한다고 결론을 내립니다. g ++의 행동이 부합 하는가?

답변

24

Foo에 대한 이동 코드가 있으면 선택해야합니다. 클래스 반환 형식으로 함수에서 return 문에

  • , 표현은 다음과 같습니다

    함수 매개 변수를 명시 적으로 반환 문에서 복사 생략 (FDIS의 §12.9p31, 첫 번째 글 머리 기호)에서 제외됩니다

그러나 (함수 나 잡을 절 매개 변수 이외의) 비 휘발성 자동 객체 의 이름은 다음 단락은 명시 적으로 제공

복사 작업의 생략에 대한 기준이 충족

또는 소스 객체가 함수 매개 변수 및 복사 할 대상이라는 사실을 저장 충족 될이 지정되어 고려로 다시 ctors 이동 lvalue에 의해 복사물의 생성자를 선택하기위한 과부하 해결은 먼저 객체가의 값으로 지정된 것처럼 으로 수행됩니다. ...

(강조는 모두 따옴표 내 꺼야.)

+9

Upvoted. 이것은 초안에 대한 상대적으로 늦은 변화로 어디서나 구현되지 않은 이유를 설명합니다. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1148 –

12

이것은 유효한 코드 - G ++의 행동은 비 준수합니다. MSVC10은이 동작을 지원합니다.

+0

귀하의 수사를 존중하는 동안 귀하는 "유효한"것을 정당화하지 못합니다. MSVC는 표준이 금지하는 일부 (편리한) 전표 (예 : 클래스 본문 내 비 const 참조 및 멤버 함수 특수 바인딩)를 허용하지 않고 느슨해 진 것으로 알려져 있습니다. –

+2

@Matthieu : MSVC10이 지원했기 때문에 * 유효하지 않다고 말했습니다. 표준이 그렇게 말하기 때문에 그것은 유효합니다. – Puppy

+2

나는 이해했다, 그러나 아직도 정당화가 없다. –

관련 문제