`X :: X(const X&&)`Const移动构造函数?

时间:2012-12-31 10:56:34

标签: c++ c++11

  

可能重复:
  Move constructor signature

struct X
{
    X(X&);         // (1)
    X(X&&);        // (2)
    X(const X&);   // (3)
    X(const X&&);  // (4)
};

是否有任何情况会在重载决议中选择(4)

2 个答案:

答案 0 :(得分:9)

是。一种情况是当你有一个const返回值的函数时:

const X f();

X x(f());

答案 1 :(得分:2)

另一种情况是当您将std::move应用于const对象时,如下例所示:

#include <iostream>

using namespace std;

struct X
{
    X() { cout << "default" << endl; }
    X(X&) { cout << "non const copy" << endl; }    // (1)
    X(X&&) { cout << "non const move" << endl; }   // (2)
    X(const X&) { cout << "const copy" << endl; }  // (3)
    X(const X&&){ cout << "const move" << endl; }  // (4)
};

void f(X const x)
{
}

int main()
{
    X const x;
    f(std::move(x));

    return 0;
}

上一个答案(X const f())中提到的情况可能不太常见,因为在执行RVO时,编译器大部分时间都忽略了移动构造函数(即使构造函数有侧面,也可以这样做 - 效果)。

const对象移动到另一个const对象作为逻辑操作确实有意义,如果您没有定义const移动构造函数,那么您将不被允许这样做。移动只是转移所有权,所以在我看来,作为一种逻辑操作,它应该得到支持。

虽然确实从高级别的角度来看你不应该修改const对象并确实移动一个对象需要修改它(在大多数情况下),但是有一些众所周知的类似情况。可以在幕后修改const对象,以实现更高级别的概念操作。考虑一个需要锁定非const成员互斥锁的const成员函数的例子:你可以将互斥变量声明为mutable,将其视为非const对象。

因此,即使在这种情况下,我将其视为const移动构造函数中的合法操作(只要需要)来修改移动对象的mutable成员(可能是一些布尔标记到由对象的析构函数检查)。请注意,如果从上面的代码中删除const构造函数(3)和(4),那么它将无法编译。如果仅删除(4),则将选择复制构造函数(3) - 这意味着您将无法移动const对象。