考虑当从函数中返回启用了移动语义的“整个”对象时,例如 std::basic_string<>
:
std::wstring build_report() const
{
std::wstring report;
...
return report;
}
那么,我是否实际上可以期望做出“最佳”选择,使用具有移动语义的返回字符串,如下所示:
const std::wstring report(std::move(build_report()));
还是我应该依赖 (N)RVO 来发生
const std::wstring report(build_report());
甚至可以使用const引用将临时对象绑定到
const std::wstring& report(build_report());
有没有一种方案可以确定性地选择这些选项?请注意,上面使用的std::wstring只是启用了移动语义类型的示例。它同样可以用你的arbitrary_large_structure进行交换。我检查了在VS 2010中运行速度优化的发布版本时生成的汇编代码。std::wstring build_report(const std::wstring& title, const std::wstring& content)
{
std::wstring report;
report.append(title);
report.append(content);
return report;
}
const std::wstring title1(L"title1");
const std::wstring content1(L"content1");
const std::wstring title2(L"title2");
const std::wstring content2(L"content2");
const std::wstring title3(L"title3");
const std::wstring content3(L"content3");
int _tmain(int argc, _TCHAR* argv[])
{
const std::wstring report1(std::move(build_report(title1, content1)));
const std::wstring report2(build_report(title2, content2));
const std::wstring& report3(build_report(title3, content3));
...
return 0;
}
最有趣的两个结果:
- 显式调用
std::move
以使用移动构造函数来三倍增加指令计数。 - 正如 James McNellis 在下面他的回答中所述,
report2
和report3
的生成汇编确实与显式调用std::move
相比少了三倍的指令。
move
没有被内联和消除真的很奇怪。 - James McNellisstd::move
的问题;我确实觉得这很令人困惑。我将度假到下周末结束,所以需要几周时间才能回复您。 - James McNellis