简体   繁体   English

我应该总是在构造函数中使用 std::move 吗?

[英]Should I always use std::move in a constructor?

Are the move semantics used in Example A necessary, and which struct is superior?示例 A 中使用的移动语义是否必要,哪个结构更好?

Example A:示例 A:

struct A
{
    std::string a;
    A( std::string a ) : a( std::move(a) ){ }
};

Example B:示例 B:

struct B
{
    std::string b;
    B( const std::string& b ) : b( b ){ }
};

I don't believe this is a duplicate question.我不相信这是一个重复的问题。 I am asking specifically which example is superior from the perspective of using member initialization in a class constructor.我特别询问从在类构造函数中使用成员初始化的角度来看,哪个示例更好。 None of the examples or answers listed in the other question dealt with member initialization.另一个问题中列出的示例或答案均未涉及成员初始化。

I don't like that the constructor is called with a reference parameter, then copied into the member.我不喜欢使用引用参数调用构造函数,然后将其复制到成员中。 It seems that it could be wasteful to have multiple copy operations.似乎有多个复制操作可能很浪费。

I want to "pipe" the data into the members as efficiently as possible but I don't want to take rvalues as the constructor parameters.我想尽可能有效地将数据“管道”到成员中,但我不想将右值作为构造函数参数。

Struct A is superior.结构A是优越的。

Moving an object is usually very cheap (and can often be completely optimized out), so typically one shouldn't care about the number of moves.移动一个对象通常非常便宜(并且通常可以完全优化),因此通常不应该关心移动的次数。 But it's important to minimize the number of copies.但尽量减少副本数量很重要。 The number of copies in example A is equal to or less than the number of copies in example B.示例 A 中的副本数等于或小于示例 B 中的副本数。

More specifically, A and B are equivalent if the original string is an L-value:更具体地说,如果原始字符串是 L 值,则 A 和 B 是等效的:

std::string s;
...
A a(s);  // one copy
B b(s);  // one copy

but A is better when the original string is an R-value:但是当原始字符串是 R 值时 A 更好:

std::string MakeString();
...
A a(MakeString());  // zero copies
B b(MakeString());  // one copy

In my opinion it is not genuine to compare both.在我看来,将两者进行比较是不真实的。

Most of the times the implemented copy constructor makes deep copy and the main intention behind is to ensure the source object is not modified.大多数情况下,实现的复制构造函数进行深复制,其背后的主要目的是确保源对象不被修改。

std::move which eventually calls move constructor for rvalue reference, just copies the pointer and can set the source object pointer to NULL. std::move 最终为右值引用调用移动构造函数,只复制指针并可以将源对象指针设置为 NULL。 This scenario is mainly for temporary objects .这种情况主要是针对临时对象

So both examples are meant for two different purpose , one (copy constructor) when you want source object to be untouched, and the other (std::move) is meant for dealing temporary objects.所以这两个例子都有两个不同的目的一个(复制构造函数)当你希望源对象不被修改时,另一个(std::move)用于处理临时对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM