为什么不将右值引用定义为右值表达式?

beg*_*ses 5 c++ rvalue-reference move-semantics c++11

让我们考虑以下代码:

class X {
    std::vector<int> _v;
public:
    X(std::vector<int>&& v): _v(std::move(v)) {}
};
Run Code Online (Sandbox Code Playgroud)

编译器仅针对可移动的对象调用此构造函数。那么,为什么不只是将右值引用定义为右值表达式,而不是每次都为它们写std :: move呢?

ctor成员初始化列表如下所示:

_v(v)
Run Code Online (Sandbox Code Playgroud)

但这仍然是一个举动,而不是复制。

How*_*ant 13

尽管std::move在这种常见情况下要求这样做有些不幸,但人们认为,在某些情况下,导致运行时错误的隐式移动更为有害。

例如:

class Y
{
public:
    Y(const std::vector<int>& v);
};

class X {
    std::vector<int> v_;
    Y                y_;
public:
    X(std::vector<int>&& v): v_(v), y_(v) {}
};
Run Code Online (Sandbox Code Playgroud)

在此修改示例中,的构造函数X使用了v两次。如果第一次使用v隐式移动,那么第二次使用v很可能不会获得期望值。

因此,为避免意外的“移动后使用”,如果它具有名称,则可以多次使用它,因此更安全地将其视为左值。