c++ - 返回默认构造对象是否会阻止 NRVO?
问题描述
假设我有一个类似的功能:
using std::vector;
vector<int> build_vector(int n)
{
if (some_condition(n)) return {};
vector<int> out;
for(int x : something())
{
out.push_back(x);
}
return out;
}
return {}
函数开头的是否会阻止 NRVO?我很好奇,因为这似乎等同于以下内容:
using std::vector;
vector<int> nrvo_friendly_build_vector(int n)
{
vector<int> out;
if (some_condition(n)) return out;
for(int x : something())
{
out.push_back(x);
}
return out;
}
但我不清楚在第一种情况下是否允许编译器执行 NRVO。
解决方案
来自https://en.cppreference.com/w/cpp/language/copy_elision
在以下情况下,编译器允许但不需要省略类对象的复制和移动(C++11 起)构造,即使复制/移动(C++11 起)构造函数和析构函数具有可观察的一面-效果。对象直接构建到存储中,否则它们将被复制/移动到。这是一种优化:即使它发生并且没有调用复制/移动(C++11 起)构造函数,它仍然必须存在且可访问(就好像根本没有发生优化一样),否则程序会出错-形成:
在 return 语句中,当操作数是具有自动存储持续时间的非易失性对象的名称时,它不是函数参数或 catch 子句参数,并且属于相同的类类型(忽略 cv 限定)函数返回类型。这种复制省略的变体被称为 NRVO,“命名返回值优化”。
...
提前返回没有限制,因此两个版本都是 NRVO 的候选版本。
推荐阅读
- python - 每当在 tkinter 中由 tkraise() 引发时更新/更新倒计时帧
- excel - Lastrow 变量转换为公式
- jasper-reports - 从 Jasper Studio (TIBCO Jaspersoft Studio) 生成 pdf 时出现孟加拉语 unicode 渲染问题
- node.js - 通过队列和 node.js 中的工作人员调整图像大小
- javascript - 根据多个标记 Lng,Lat 设置地图边界
- swift - 如何同时调用多个操作
- postgresql-9.6 - Postgresql-9.6 备份
- azure-devops - VSTS 中是否有等效的 Jira-Releases?
- javascript - Javascript在出错后继续运行代码
- android - Appium发送指令无反馈,手动滑动屏幕做出反应