많은 경우에 함수에서 로컬을 반환 할 때 RVO가 실행됩니다. 그러나 std::move
을 명시 적으로 사용하면 RVO가 발생하지 않을 때 적어도 RVO가 가능한 경우 계속 적용됩니다. 그러나 이것이 그렇지 않은 것으로 보입니다. std :: move가 RVO를 막는 이유는 무엇입니까?
#include "iostream"
class HeavyWeight
{
public:
HeavyWeight()
{
std::cout << "ctor" << std::endl;
}
HeavyWeight(const HeavyWeight& other)
{
std::cout << "copy" << std::endl;
}
HeavyWeight(HeavyWeight&& other)
{
std::cout << "move" << std::endl;
}
};
HeavyWeight MakeHeavy()
{
HeavyWeight heavy;
return heavy;
}
int main()
{
auto heavy = MakeHeavy();
return 0;
}
나는 VC++ (11)와 GCC 4.71, 디버그 및 릴리스 (
-O2
) 설정이 코드를 테스트했다. 복사본 매개 변수가 호출되지 않습니다. 이동 ctor는 VC++ 11에 의해서만 디버그 구성에서 호출됩니다. 사실, 모든 이들 컴파일러와 함께 잘 될 것 같습니다,하지만 내 지식에, RVO 선택 사항입니다.
그러나, 나는 명시 적으로 move
를 사용하는 경우 :
HeavyWeight MakeHeavy()
{
HeavyWeight heavy;
return std::move(heavy);
}
가 이동 ctor에 항상
라고합니다. 그래서 그것을 "안전하게"만들려고하면 악화됩니다.내 질문 :
- 왜 std::move
은 RVO를 방지합니까?
- RVO에 의존하는 것이 "최선을 기원합니다"보다 나은 이유는 무엇이며 언제 명시 적으로 std::move
을 사용해야합니까? 즉, 어떻게 RVO가 적용되지 않으면 컴파일러 최적화가 작업을 수행하고 여전히 강제로 이동하도록 할 수 있습니까?
요즘 사람들은 왜 요즘 "최고를 향한 희망"에 대해 이야기합니까? 어떤 종류의 컴파일러가 C++ 11을 지원하지만 RVO를 제대로 지원하지 못합니까? –
복사 elion (RVO의 메커니즘)은 특정 엄격한 조건에서만 허용됩니다. 'std :: move'를 쓰면 이러한 조건이 충족되지 않습니다. –
@KerrekSB 그리고 이러한 상태가 std :: move로 방지되는 이유는 무엇입니까? – cdoubleplusgood