据我了解,为了使编译器能够进行命名返回值优化(NRVO),必须在函数体中的任何其他值之前声明返回值。我怀疑这可能是由于在异常情况下堆栈展开的顺序,但我不确定。命名返回值必须是在函数体中声明的第一个是什么原因?
class C{};
C f(){
C ret; //NRVO possible
return ret;
}
C g(){
int i;
C ret; //NRVO not possible?
return ret;
}
用例:
auto c = f();
auto c2 = g();
修改 感谢所有回答者帮助我理解这一点,我开始怀疑Chandler Carruth在这里的陈述:http://www.youtube.com/watch?v=fHNmRkzxHWs分钟32:30可能会误导和/或我只是误解了它。首先声明返回变量似乎并不重要。
答案 0 :(得分:0)
该标准对复制省略方面的变量声明/定义顺序没有要求。请注意,标准说“实施允许”,而不是它应该,应该等。我们可以看到clang
and gcc
发生了复制省略,但MSVC
没有,进一步巩固了这是一个实现定义的优化。
§12.8/ 31描述了复制省略:
[..] 在下列情况下(可以合并到以下情况),允许复制/移动操作的省略,称为复制省略 消除多份副本):
- 在具有类返回类型的函数的return语句中,何时 表达式是非易失性自动对象的名称(其他 比函数或catch子句参数)与之相同 cv-unqualified type作为函数返回类型,copy / move 通过直接构造自动对象可以省略操作 进入函数的返回值
- [..]