"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::vector
的 move 构造函数。它调用 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 仍然是正确的。
作为右值引用和移动语义的新手,我正在尝试从 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::vector
的 move 构造函数。它调用 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 仍然是正确的。