我听到 Herb Sutter 最近的一次演讲,他建议通过 const &
传递 std::vector
和 std::string
的原因代码> 基本上消失了.他建议现在最好编写如下函数:
I heard a recent talk by Herb Sutter who suggested that the reasons to pass std::vector
and std::string
by const &
are largely gone. He suggested that writing a function such as the following is now preferable:
std::string do_something ( std::string inval )
{
std::string return_val;
// ... do stuff ...
return return_val;
}
我知道 return_val
在函数返回时将是一个右值,因此可以使用非常便宜的移动语义返回.但是,inval
仍然比引用的大小(通常实现为指针)大得多.这是因为 std::string
具有各种组件,包括指向堆的指针和用于短字符串优化的成员 char[]
.所以在我看来,通过引用传递仍然是一个好主意.
I understand that the return_val
will be an rvalue at the point the function returns and can therefore be returned using move semantics, which are very cheap. However, inval
is still much larger than the size of a reference (which is usually implemented as a pointer). This is because a std::string
has various components including a pointer into the heap and a member char[]
for short string optimization. So it seems to me that passing by reference is still a good idea.
谁能解释一下赫伯为什么会这么说?
Can anyone explain why Herb might have said this?
Herb之所以这么说,就是因为这样的案例.
The reason Herb said what he said is because of cases like this.
假设我有函数 A
调用函数 B
,它调用函数 C
.而A
将一个字符串通过B
传入C
.A
不知道也不关心C
;所有A
知道的是B
.即C
是B
的一个实现细节.
Let's say I have function A
which calls function B
, which calls function C
. And A
passes a string through B
and into C
. A
does not know or care about C
; all A
knows about is B
. That is, C
is an implementation detail of B
.
假设 A 的定义如下:
Let's say that A is defined as follows:
void A()
{
B("value");
}
如果 B 和 C 通过 const&
取字符串,那么它看起来像这样:
If B and C take the string by const&
, then it looks something like this:
void B(const std::string &str)
{
C(str);
}
void C(const std::string &str)
{
//Do something with `str`. Does not store it.
}
一切都很好.你只是在传递指针,没有复制,没有移动,每个人都很高兴.C
采用 const&
因为它不存储字符串.它只是使用它.
All well and good. You're just passing pointers around, no copying, no moving, everyone's happy. C
takes a const&
because it doesn't store the string. It simply uses it.
现在,我想做一个简单的改变:C
需要将字符串存储在某处.
Now, I want to make one simple change: C
needs to store the string somewhere.
void C(const std::string &str)
{
//Do something with `str`.
m_str = str;
}
你好,复制构造函数和潜在的内存分配(忽略短字符串优化 (SSO)).C++11 的移动语义应该可以删除不必要的复制构造,对吗?并且 A
传递一个临时的;C
没有理由必须复制数据.它应该带着被给予的东西潜逃.
Hello, copy constructor and potential memory allocation (ignore the Short String Optimization (SSO)). C++11's move semantics are supposed to make it possible to remove needless copy-constructing, right? And A
passes a temporary; there's no reason why C
should have to copy the data. It should just abscond with what was given to it.
除非它不能.因为它需要一个const&
.
Except it can't. Because it takes a const&
.
如果我更改 C
以按值获取其参数,那只会导致 B
复制到该参数中;我一无所获.
If I change C
to take its parameter by value, that just causes B
to do the copy into that parameter; I gain nothing.
因此,如果我只是通过所有函数按值传递 str
,依靠 std::move
对数据进行混洗,我们将不会有这个问题.如果有人想坚持下去,他们可以.如果他们不这样做,哦,好吧.
So if I had just passed str
by value through all of the functions, relying on std::move
to shuffle the data around, we wouldn't have this problem. If someone wants to hold on to it, they can. If they don't, oh well.
是不是更贵了?是的;移动到一个值比使用引用更昂贵.比副本便宜吗?不适用于具有 SSO 的小字符串.值得吗?
Is it more expensive? Yes; moving into a value is more expensive than using references. Is it less expensive than the copy? Not for small strings with SSO. Is it worth doing?
这取决于您的用例.你有多讨厌内存分配?
It depends on your use case. How much do you hate memory allocations?
这篇关于是通过 const std::string & 的日子吗?作为参数结束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!