"Inherit" 移动操作无法访问 base-class 成员变量

"Inherit" move operations without access to base-class member variables

作为右值引用和移动语义的新手,我正在尝试从 std::vector 派生一个简单的模板 class(我保证我会小心缺少虚拟析构函数)。对于 "inherit" 移动构造函数,我简单地将基础 class 和 std::move

调用
template <typename T>
class Vec: public std::vector<T> {
  public:
    ...
    //move ctors
    Vec(Vec&& v): std::vector<T>(v) { //move extra members with std::move }
    explicit Vec(std::vector<T>&& v): std::vector<T>(v) { //same as above }
    ...
};

根据我对 C++ 的理解,这似乎值得信赖。但是,我对移动赋值运算符的方法信心不足,

    //assignment
    Vec& operator=(const Vec& v) {
        std::vector<T>::operator=(v);
        if (&v != this)
          //copy extra members
        return *this;
    }
    //move assignment
    Vec& operator=(Vec&& v) {
        std::vector<T>::operator=(v);
        //move extra members with std::move
        return *this;
    }

这是实现我想要的东西的万无一失的方法吗?在良好实践方面是否有更好的替代方案?

which seems trustworthy ...

似乎值得信赖。但事实并非如此。你看,这个:

Vec(Vec&& v)

是移动构造函数。所以它会被调用一个右值。但是一旦我们进入这里,v 就是一个左值!经验法则:如果它有名字,它就是一个左值。所以这部分:

: std::vector<T>(v)

不调用 std::vectormove 构造函数。它调用 copy 构造函数。您需要明确地将 v 转换为右值才能做正确的事情:

Vec(Vec&& v) : std::vector<T>(std::move(v)) { }
explicit Vec(std::vector<T>&& v): std::vector<T>(std::move(v)) { }

或者,更好的是:

Vec(Vec&& ) = default;

同样,编写赋值运算符的万无一失的方法就是 default-ing 它们:

Vec& operator=(Vec const& ) = default;
Vec& operator=(Vec&& ) = default;

但是如果你真的有特殊的逻辑,确保你也记得在那里转换为右值:

Vec& operator=(Vec&& v) {
    std::vector<T>::operator=(std::move(v));
    // stuff
    return *this;
}

或者更好的是,将您的特殊逻辑移动到一个独立的单元中,这样 default-ing 仍然是正确的。