通过Value或Reference传递std :: string

Nor*_*löw 72 c++ string std move-semantics

可能重复:
传递const std :: string&作为参数的日期是多少?

如果std::string支持移动语义,我应该通过值传递还是通过引用传递(到非内联函数)?那么使用小字符串优化(SSO)的实现呢?

lin*_*r27 128

根据您对字符串的操作,有多个答案.

1)使用字符串作为id(不会被修改).通过const引用传入它可能是最好的主意:(std::string const&)

2)修改字符串但不希望调用者看到该更改.通过值传递它是优选的:(std::string)

3)修改字符串但希望调用者看到该更改.通过引用传递它是优选的:(std::string &)

4)将字符串发送到函数中,函数的调用者将永远不会再使用该字符串.使用移动语义可能是一种选择(std::string &&)

  • #4是不必要的,因为通过在他的参数上使用`std :: move`并调用by-value版本,这是可以而且应该在调用者方面处理的事情. (21认同)
  • @BenjaminLindley完全没有,`&&`防止意外地通过副本传递参数. (2认同)
  • @Destructor它从字符串文字构造一个`std :: string`并将其作为参数传递。然后,它从参数复制构造成员字符串。因此,有两个分配和两个O(n)数组复制操作(每个参数)。您应该按值使用params并将它们“ std :: move”移入成员。这样,每个参数将只有一个分配,一个O(n)数组副本和一个O(1)移动。 (2认同)

ems*_*msr 21

查看C++ 11的答案.基本上,如果你传递一个左值的左值参考

这篇文章:

void f1(String s) {
    vector<String> v;
    v.push_back(std::move(s));
}
void f2(const String &s) {
    vector<String> v;
    v.push_back(s);
}
Run Code Online (Sandbox Code Playgroud)

"对于左值参数,'f1'有一个额外的副本来传递参数,因为它是按值,而'f2'有一个额外的副本来调用push_back.所以没有区别;对于rvalue参数,编译器必须创建一个临时的'String(L"")'然后将临时值传递给'f1'或'f2'.因为'f2'可以在参数是临时值(这是一个rvalue)时利用move ctor,所以通过'f1'和'f2'的参数现在相同."

继续:"这意味着在C++ 11中,我们可以通过在以下情况下使用按值传递方法获得更好的性能:

  1. 参数类型支持移动语义 - 所有标准库组件都在C++ 11中完成
  2. 移动构造函数的成本比复制构造函数(时间和堆栈使用)便宜得多.
  3. 在函数内部,参数类型将被传递给另一个支持复制和移动的函数或操作.
  4. 通常将临时文件作为参数传递 - 您可以组织代码来执行此操作.

"

OTOH,对于C++ 98,最好通过引用传递 - 减少数据被复制.传递const或非const取决于您是否需要更改参数.


Vau*_*ato 6

我相信正常的答案是,如果您需要在函数中复制它,则应该按值传递。否则通过常量引用传递它。

这是一个很好的讨论:http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

  • 内容已删除,仍可在此处查看:http://web.archive.org/web/20120908071416/http://cpp-next.com/archive/2009/08/want-speed-pass-by-value (2认同)