我有一个包含指向对象的指针的类及其子类。出于明显的原因,我想调用基类move构造函数的子类“ move”构造函数。使用MSVS 2017编译器似乎无法正常工作。
template<class SubT>
class MyMovingBase {
typedef MyMovingBase<MtY> ThisT;
protected:
MyMovingBase(const ThisT &src) {
// update copy and or reference DO NOT Move
}
MyMovingBase(ThisT &&src) {
// move stuff from src to this, invalidate src
}
};
class Subclass
: public MyMovingBase<SubClass>
{
public:
Subclass(const Subclass &src) : MyMovingBase<SubClass>(src) {
// does what is expected, calls copy constructor.
}
Subclass(Subclass &&src) : MyMovingBase<SubClass>(src) {
// the above initializer calls copy constructor and NOT
// the move constructor for MyMovingBase !!!!!!
}
};
我如何做到这一点?
我当然希望它也可以在gcc和clang中工作。
答案 0 :(得分:4)
通常,用rvalue reference
将某些变量标记为&&
并不意味着在进一步传递src
时它将保持此状态。我的意思是,毕竟,变量在构造函数的上下文中具有名称,因此可以明显地用作lvalue
。实际上,表达式src
确实是lvalue
。 src
以rvalue
的形式传递给您的构造函数,因为调用者打算将其解释为这样。
现在,在您的构造函数中,该变量实际上已被命名,使用该名称将导致一个表达式,该表达式需要显式标记为rvalue reference
才能被解释。否则,它只是一个左值。这就是为什么您必须再次move
使其被被叫方(此处为MyMovingBase::ctor
)解释为rvalue
的情况,其内容才可以从原始对象中移出。
因此,François的评论是正确的。使用
Subclass(Subclass &&src) : MyMovingBase<SubClass>(std::move(src))
起到了作用。