C++传递std :: string的最快方法?

ahc*_*cox 1 c++ deep-copy stdstring c++11 c++98

注意我问这是一个std::string特定的问题,而不是一般如何传递一个对象.

我会删除这个问题,但由于它的答案,我不被允许.我相信答案可能倾向于堕落,以回答更常见的问题:"用C++传递对象的最佳方法是什么?" 关于堆栈溢出的这些更一般的答案有许多重复,即使这个精确的问题本身可能不是重复.这种退化可能是因为问题是一个不合适的问题,而且std :: string类没有什么特别之处.这个问题并没有高度投票,这表明它并不有趣.在那种情况下我很糟糕.也许一个mod会看到这个黑色的文字,怜悯我并杀死这个问题.

以下哪个签名表示将非const std::string实例传递给不修改它的函数的最快方法,考虑到调用站点上调用的总体开销,包括底层字符数组的深层副本是否会在通话之前产生?

extern void eat_string_by_value          (std::string s);
extern void eat_const_string_by_value    (const std::string s);
extern void eat_string_by_reference      (std::string& s);
extern void eat_const_string_by_reference(const std::string& s);
Run Code Online (Sandbox Code Playgroud)

注意我问这是一个std::string特定的问题,而不是一般如何传递一个对象.特别是,我的问题是由以下因素刺激:

  • std :: string handle-body implementation:是否有任何签名暗示了在调用站点的字符串主体及其后备字符数组的深层副本?
    • 注意复制句柄(应该是轻量级)和复制主体(这将涉及内存分配)之间的区别.
  • C++ 98与C++> = 11:这个版本划分的任何一方是否有不同的答案?

我没有看到我的问题是前一个问题的副本,它本身标记为一个普通对象的副本,传递一个< 传递参数为std :: string或const std :: string&?>因为这些特定类型的详细点.

关于相关问题的一个有趣答案:

Ded*_*tor 6

extern void eat_string_by_value          (std::string s);        // value
extern void eat_const_string_by_value    (const std::string s);
extern void eat_string_by_reference      (std::string& s);       // reference
extern void eat_const_string_by_reference(const std::string& s); // const-ref
Run Code Online (Sandbox Code Playgroud)

首先,你错过了一个选项(从C++ 11开始):

extern void eat_string_by_rvaluereference(std::string&& s);      // rvalue-ref
Run Code Online (Sandbox Code Playgroud)

下一点,您的两个选项是相同的,因为顶级参数-cv限定符不是函数签名的一部分:

extern void eat_string_by_value          (std::string s);
extern void eat_const_string_by_value    (const std::string s);
Run Code Online (Sandbox Code Playgroud)

那么,让我们看看:

  1. 通过传递:
    缺点:调用者必须复制或移入参数.除非它在那里建造.
    优势:与所有人结合.Callee有自己的副本进行修改.
  2. 通过引用传递:缺点:仅绑定到左值(非临时对象).
    优点:Callee可以修改传递的参数.
  3. 通过const-ref传递.缺点:如果需要,Callee必须自己制作副本.
    优点:与所有人结合.
  4. 通过rvalue-ref传递.
    缺点:无法绑定到左值.复制绑定到const对象.
    优点:可以清除传递的参数.

因此,按值几乎总是表示副本(或至少是一个移动),按引用表示从不复制(但对参数的必要限制),所有其余的仅在需要转换时复制.
By-const-ref意味着不能修改参数,并且by-rvalue-ref意味着可以重用其资源,这可能会在以后保存副本.