C++ 哪种功能结构更好?

C++ 哪种功能结构更好?,c++,c++11,rvalue-reference,nrvo,C++,C++11,Rvalue Reference,Nrvo,请看以下代码: class MyClass{ public: MyClass(){} MyClass(MyClass &&){} MyClass(const MyClass &){} }; MyClass f1(){ MyClass &&o=MyClass(); /*...*/ return std::move(o);//or return static_cast<MyClass &&&

请看以下代码:

class MyClass{
public:
    MyClass(){}
    MyClass(MyClass &&){}
    MyClass(const MyClass &){}
};
MyClass f1(){
    MyClass &&o=MyClass();
    /*...*/
    return std::move(o);//or return static_cast<MyClass &&>(o);
}
MyClass f2(){
    MyClass o=MyClass();
    /*...*/
    return o;
}


int main(int, char **){
    auto a=f1();
    auto b=f2();
}
函数f2是返回对象的正常形式。可以应用,并且可以避免额外的复制构造函数调用。f1是使用右值引用的新表单。对于不支持NRVO但支持rvalue引用的系统,调用move构造函数而不是copy构造函数,在大多数情况下,这会被认为是更好的方法

f1的问题是:在这种情况下,有没有支持NRVO的编译器?毕竟,这似乎是未来更好的形式

在这种情况下,是否有NRVO的编译器支持

定义编译器支持

f1完全破坏了编译器优化MyClass副本的能力。让我们详细了解f1

MyClass &&o=MyClass();
这将创建一个临时变量,而不是堆栈变量。然后,该临时变量被绑定到一个名为o的r值引用,该引用将临时变量的生存期延长到函数的末尾

return std::move(o); //or return static_cast<MyClass &&>(o);
f2是否:

如果NVRO不存在,则您有:

create stack variable
copy/move from stack variable to return value
elide copy/move from stack variable to `b`.
因此,f2最坏情况下等于f1。而且更有可能更好

请不要试图超越编译器。让复制省略完成它的工作

在这种情况下,是否有NRVO的编译器支持

定义编译器支持

f1完全破坏了编译器优化MyClass副本的能力。让我们详细了解f1

MyClass &&o=MyClass();
这将创建一个临时变量,而不是堆栈变量。然后,该临时变量被绑定到一个名为o的r值引用,该引用将临时变量的生存期延长到函数的末尾

return std::move(o); //or return static_cast<MyClass &&>(o);
f2是否:

如果NVRO不存在,则您有:

create stack variable
copy/move from stack variable to return value
elide copy/move from stack variable to `b`.
因此,f2最坏情况下等于f1。而且更有可能更好


请不要试图超越编译器。让复制省略完成它的工作。

这就是当前编译器MSVC10/gcc主干的工作方式: 假设MyClass是可移动的

f1 : move   
f2 :   
worst case : move 
best case : NRVO 
假设MyClass不可移动:

f1 : copy    
f2 :    
worst case : copy    
best case : NRVO 

因此,即使编译器变得更好,并开始为f1这样的函数执行NRVO,为什么还要在f2经典C++03函数已经是最佳函数的情况下使代码复杂化呢?

当前的编译器MSVC10/gcc主干就是这样工作的: 假设MyClass是可移动的

f1 : move   
f2 :   
worst case : move 
best case : NRVO 
假设MyClass不可移动:

f1 : copy    
f2 :    
worst case : copy    
best case : NRVO 

因此,即使编译器变得更好,并开始为f1这样的函数执行NRVO,为什么还要在f2经典C++03函数已经是最佳函数的情况下麻烦使代码复杂化呢?

对于不支持NRVO但支持右值引用的系统,我强烈怀疑这样的系统实际上并不存在。我想确认一下。哦。。。哪个更好这是一个决定性地结束一切的问题,哪一个更好,a还是b?有问题,对吧???提示:选择一个更具描述性的标题C++11的设计人员会竭尽全力使最明显的代码也是最好的代码。请参阅。对于不支持NRVO但支持右值引用的系统,我强烈怀疑这种系统实际上并不存在。我想确认一下。哦。。。哪个更好这是一个决定性地结束一切的问题,哪一个更好,a还是b?有问题,对吧???提示:选择一个更具描述性的标题C++11的设计人员会竭尽全力使最明显的代码也是最好的代码。看,你说得不对。我指定返回值为MyClass对象,因此编译器必须返回引用的副本,而不是返回要立即销毁的对象引用。在这种情况下,我的编译器显然调用了move构造函数。@EarthEngine:很公平。但这并不能改变这样一个事实,即你从中得不到任何东西。请看我的编辑。你错了。我指定返回值为MyClass对象,因此编译器必须返回引用的副本,而不是返回要立即销毁的对象引用。在这种情况下,我的编译器显然调用了move构造函数。@EarthEngine:很公平。但这并不能改变这样一个事实,即你从中得不到任何东西。请参阅我的编辑。