ric*_*cab 2 copy return-by-reference move-semantics c++11 return-by-value
在过去,如果我想要一个对象的字符串表示A,我会写一些带有签名的东西,void to_string(const A& a, string& out)以避免额外的副本.这仍然是C++ 11中的最佳实践,具有移动语义和所有?
我已经阅读了一些关于其他上下文的评论,这些评论建议依赖于RVO而不是写作string to_string(const A& a).但RVO并不能保证会发生!那么,作为to_string的程序员,我怎么能保证字符串不会被不必要地复制(独立于编译器)?
假设您的函数中的代码具有以下形式:
std::string data = ...;
//do some processing.
return data;
Run Code Online (Sandbox Code Playgroud)
std::string如果elision不可用,则需要调用'move构造函数.最糟糕的情况是,你可以从你的内部字符串移动.
如果您负担不起移动操作的费用,那么您必须将其作为参考传递.
话虽如此......你是否担心编译器无法内联短函数?您是否担心小包装是否会被无法正确优化?编译器不能优化for循环等的可能性是否打扰了你?你觉得是否if(x < y)快于if(x - y < 0)?
如果不是......那你为什么要关心复制/移动省略("返回值优化"的技术术语,因为它在更多地方使用)?如果您使用的是不支持复制省略的编译器,那么您使用的是可怕的编译器,可能无法支持大量其他优化.出于性能考虑,您最好花时间升级编译器,而不是将返回值转换为引用.
防止副本实际发生的不可能的情况是不值得的...麻烦?代码不太可读?到底是什么?在简单回报方面加权的额外事情是什么?
"额外的事情"就是:
std::string aString = to_string(a);
Run Code Online (Sandbox Code Playgroud)
比这更具可读性:
std::string aString;
to_string(a, aString);
Run Code Online (Sandbox Code Playgroud)
在第一种情况下,它是立即显而易见的是,to_string正在初始化一个字符串.在第二个,它不是; 你要查找to_string的签名看到它采取非const参考.
第一种情况甚至不是"惯用的"; 这就是每个人通常会写它的方式.你永远不会看到to_int(a, someInt)整数的呼唤; 这是荒谬的.为什么整数创建和对象创建如此不同?作为程序员,你不应该关心是否有太多的副本发生了返回值.你只需要简单,明显和易于理解的方式.
| 归档时间: |
|
| 查看次数: |
208 次 |
| 最近记录: |