注意 我问这是一个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);
注意 我问这是一个std::string
特定问题,而不是一般如何传递一个对象。特别是,我的问题受到以下因素的刺激:
我不认为我的问题是前一个问题的副本,它本身被标记为传递一个<的一般对象的副本。 Pass arguments as std::string or const std::string&?>因为这些特定类型的详细点。
关于相关问题的一个有趣答案:
答案 0 :(得分: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
首先,您错过了一个选项(自C ++ 11起):
extern void eat_string_by_rvaluereference(std::string&& s); // rvalue-ref
接下来,两个选项是相同的,因为顶级参数-cv限定符不是函数签名的一部分:
extern void eat_string_by_value (std::string s);
extern void eat_const_string_by_value (const std::string s);
所以,让我们看看:
因此, by-value 几乎总是意味着副本(或至少是一个移动), by-reference 意味着永远不会复制(但对参数的必要限制) ,如果需要转换,所有其余的仅复制 By-const-ref 表示无法修改参数, by-rvalue-ref 表示可以重复使用其资源,这可能会在以后保存副本。< / p>
答案 1 :(得分:2)
以下哪个签名表示将非const std :: string实例传递给不修改它的函数的最快方法,同时考虑到调用站点的调用的总体开销,包括是否为在调用之前会生成基础字符数组的副本吗?
取决于。在所有方面,没有一种方法最适合所有情况。
主要变量:
没有一个答案/签名对每个案例都是理想的。
std :: string handle-body implementation:是否有任何签名暗示在主叫站点的字符串主体及其支持字符数组的深层副本?
某些实现使用COW(Copy On Write),但在C ++ 11中不再有效。传递值需要一份副本。如果您的库实现了SSO,那么对于短字符串,副本可能很快(=没有堆分配)。
C ++ 98与C ++&gt; = 11:这个版本划分的任何一方是否有不同的答案?
如上所述,COW不再有效。您可能会看到非常不同的性能特征。