【问题标题】:Is it necessary to define move constructors from different classes?是否有必要从不同的类定义移动构造函数?
【发布时间】:2011-06-17 21:03:39
【问题描述】:

考虑以下几点:

struct X
{
    Y y_;

    X(const Y & y) :y_(y) {}    
    X(Y && y) :y_(std::move(y)) {}
};

为了充分利用移动语义,是否有必要定义像第二个这样的构造函数?还是会在适当的情况下自动处理?

【问题讨论】:

  • 隐式生成移动构造函数或赋值运算符in certain circumstances。由于您在此处声明了一个复制构造函数,因此您还必须自己声明和定义一个适当的移动构造函数。但是,您可以删除这两者并在您的特定情况下具有相同的行为。
  • @James:方便的信息。但是,我没有在这里定义复制构造函数。我定义了一个从 Y 到 X 的构造函数。
  • 哦。很抱歉,我只看到了字母,并认为它们都是一样的。

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


【解决方案1】:

是的,但不是。你的代码应该是这样的:

struct X
{
    Y y_;

    X(Y y) : // either copy, move, or elide a Y
    y_(std::move(y)) // and move it to the member
    {} 
};

如果您曾经在设计中说“我需要我自己的数据副本”*,那么您应该按值获取参数并将其移动到需要的位置。决定如何构造该值不是您的工作,这取决于该值的可用构造函数,所以让它做出选择,不管它是什么,并处理最终结果。

*这当然也适用于函数,例如:

void add_to_map(std::string x, int y) // either copy, move or elide a std::string
{
    // and move it to where it needs to be
    someMap.insert(std::make_pair(std::move(x), y));
}

请注意,这在某种程度上也适用于 C++03,如果一个类型是默认可构造和可交换的(无论如何都是移动的):

// C++03
struct X
{
    std::string y_;

    X(std::string y) // either copy or elide a std::string
    {
        swap(y_, y); // and "move" it to the member
    } 
};

虽然这似乎没有被广泛使用。

【讨论】:

  • 正是我想要的,一种在一个函数中完成它们的方法。谢谢 GMan。
【解决方案2】:

是的,这是必要的。 const ref 只能是副本,不能是移动。

【讨论】:

    猜你喜欢
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 2014-04-23
    相关资源
    最近更新 更多