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:很公平。但这并不能改变这样一个事实,即你从中得不到任何东西。请参阅我的编辑。