是否有必要从不同的类定义移动构造函数?

时间:2011-01-29 20:30:57

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

请考虑以下事项:

struct X
{
    Y y_;

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

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

2 个答案:

答案 0 :(得分:7)

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

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
    } 
};

虽然这似乎并没有那么广泛。

答案 1 :(得分:1)

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