는이 당신의 방법을 변경하는 것입니다 가장 좋은 방법 :
반환 된 객체가를 rvalue해야하는 기능을 말할 필요가 없습니다
std::string StringTest()
{
std::string hello_world("Testing...");
return hello_world;
}
, 이것은 값의 존재에서 자동으로 제공 일시적입니다. 즉, 호출 사이트에서 어떤 이름에도 구속되지 않습니다. 따라서 초기화 된 유언 값은 수동으로 그러한 의도를 표현할 필요없이 (함수 내부의 임시가 완전히 생략되지 않는 한) 이동 구성되어 있습니다.
또한 반환 유형이 std::string
이므로 rvalue-reference가 아닌 값으로 반환하므로 반환하기 전에 반환 인수를 이동해야합니다. 실제로 std::move
을 호출하면 값을 반환하기 전에 불필요한 이동 생성자를 수행하도록 컴파일러를 속이는 것 외에는 아무런 효과가 없습니다. 이러한 트릭은 코드를 약간 더 복잡하게 만들거나 실행 속도를 늦추는 것 이외의 용도로 사용되지 않습니다.
값으로 돌아가고 싶습니까? 한 가지 이유는 Return Value Optimization (RVO)입니다. 대부분의 컴파일러는 이것을 수행합니다. 즉, 영리 해지기 위해 노력하고 참조를 반환하는 것보다 더 쉽게 벗어난 "복사본"을 반환하는 것이 좋습니다.
RVO를 적용 할 수없는 경우에도 rvalue-reference로 반환하면 여전히 반환되는 방식이 변경되지 않습니다. 값이 반환되면 호출 사이트에서 임시이므로 반환 값은 이미 rvalue로 전달할 수있는 rvalue가 될 것입니다. rvalue 참조는 인수로 필요한 모든 함수에 전달됩니다. 예를 들어 반환 값을 사용하여 변수를 초기화하고 반환 값이 생략되지 않으면 사용 가능한 경우 이동 생성자가 여전히 호출됩니다. 따라서 단순한 가치로 돌아가는 것만으로도 그다지 손실되지 않습니다.
이를 감안할 때, 당신은 아마 값을 잡기 위해 다음 중 하나를 수행해야합니다 값에 따라서 새로운 객체를 초기화
auto string_test_output = StringTest();
std::string string_test_output = StringTest();
값으로 돌아 오는 것을 두려워하지 마십시오. 모든 컴파일러는 NVRO를 사용하여 callsite에서 문자열을 생성합니다. – chris
옵션 A는 옵션이 아닙니다. 컴파일 오류가 발생합니다. –
@VaughnCato 반드시 그렇지는 않습니다. 컴파일되지만 std :: move는 거의 영향을 미치지 않습니다. – Agentlien