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

时间:2017-04-04 01:24:36

标签: c++ c++11 move-semantics

示例A中使用的移动语义是否必要,哪个结构更好?

示例A:

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

例B:

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

我不相信这是一个重复的问题。我特别询问从类构造函数中使用成员初始化的角度来看哪个例子更优越。其他问题中列出的示例或答案都没有涉及成员初始化。

我不喜欢使用引用参数调用构造函数,然后将其复制到成员中。似乎有多个复制操作可能会浪费。

我想" pipe"数据尽可能高效地传递给成员,但我不想将rvalues作为构造函数参数。

2 个答案:

答案 0 :(得分:2)

结构A优越。

移动对象通常非常便宜(并且通常可以完全优化),因此通常人们不必在意移动的次数。但是,重要的是最小化份数。示例A中的副本数等于或小于示例B中的副本数。

更具体地说,如果原始字符串是L值,则A和B是等效的:

 #map {
   height: 100%;
   width: 100%;
 }

 .col-md-5 {
   height: 300px;
   width: 300px;
 }

但是当原始字符串是R值时,A会更好:

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

答案 1 :(得分:0)

在我看来,比较两者并不是真的。

实施的复制构造函数大多数时候都会进行深层复制,其主要目的是确保源对象修改。

std :: move最终调用移动构造函数进行右值引用,只需复制指针并将源对象指针设置为NULL。此方案主要用于临时对象

因此,当您希望源对象不受影响时,这两个示例都用于两个不同的目的一个(复制构造函数),而其他(std :: move)用于处理临时对象。