【问题标题】:How does one call a "move" '&&' constructor in a base class? in C++ [duplicate]如何在基类中调用“移动”“&&”构造函数?在 C++ [重复]
【发布时间】:2019-06-10 18:05:06
【问题描述】:

我有一个包含指向对象的指针的类和它的子类。子类“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 中工作。

【问题讨论】:

  • MyMovingBase&lt;SubClass&gt;(std::move(src)) 请注意,src 是一个右值引用,但它本身就是一个左值,因此不会单独绑定到另一个右值引用。
  • 保存自己并使用零规则class Subclass : public MyMovingBase&lt;SubClass&gt; {} 将自动为您调用基类构造函数,因为编译器生成默认值“做正确的事”
  • 由于MyMovingBaseSubclass 是你自己的类,所以关于移动后状态的保证完全在你手中。我看不出它有什么不好的地方。
  • 糟糕的是语法而不是灵活性:)
  • @peterk 如果有人将您的某个问题标记为重复,您可以自己将其关闭为重复。 (我自己在另一个网站上发现了这个。)

标签: c++ move-semantics


【解决方案1】:

一般来说,将某个变量标记为rvalue reference&amp;&amp; 并不意味着它在进一步传递src 时保持此状态。我的意思是,毕竟变量在构造函数的上下文中有一个名称,因此显然可以用作lvalue。事实上,表达式src 确实是一个lvaluesrcrvalue 的形式传递给您的构造函数,因为调用者打算将其解释为这样。

现在,在您的构造函数中,变量实际上已命名,并且使用此名称会导致需要显式标记为 rvalue reference 的表达式才能被解释为这样。否则,它只是一个左值。这就是为什么您必须再次 move 将其解释为被调用方(此处为 MyMovingBase::ctor)为 rvalue,其内容允许从原始对象中移出。

因此,弗朗索瓦的评论是正确的。使用

Subclass(Subclass &&src) : MyMovingBase<SubClass>(std::move(src))

成功了。

【讨论】:

  • @NathanOliver 感谢您提供这个细节,我已经添加了一个句子来解决这个问题
猜你喜欢
  • 2014-07-26
  • 2011-05-22
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
  • 2012-09-28
相关资源
最近更新 更多