考虑从函数返回启用了移动语义的“整个”对象的情况,如下所示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());
如果有的话,有什么方案可以对这些选项做出确定性选择?
编辑 1:请注意,std::wstring
上面的用法只是启用移动语义的类型的示例。它也可以换成你的arbitrary_large_structure
. :-)
编辑 2:我在 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
使用report1
移动构造函数会使指令计数增加三倍。 - 正如 James McNellis 在下面的回答中所指出的那样,
report2
并且report3
确实生成了相同的程序集,其指令比显式调用少 3 倍std::move
。