【问题标题】:Bind rvalue ref to lvalue ref class member将右值引用绑定到左值引用类成员
【发布时间】:2020-03-06 16:11:01
【问题描述】:

我有以下定义

class Expression {
public:
  virtual int evaluate() const = 0;
  virtual std::string to_string() const = 0;
};

class Constant : public Expression {
  int value;

public:
  Constant() = delete;
  Constant(int value) : value(value) {}
  Constant(Constant&& c) = default;

  virtual int evaluate() const { return value; }
  virtual std::string to_string() const { return std::to_string(value); }
};

class BinaryOperator : public Expression {
protected:
  const Expression& leftOperand;
  const Expression& rightOperand;

public:
  BinaryOperator() = delete;
  BinaryOperator(const Expression& left, const Expression& right)
    : leftOperand{left}, rightOperand{right} {}
  BinaryOperator(Expression&& left, Expression&& right) // (2)
    : leftOperand(std::move(left)), rightOperand(std::move(right)) {}
  virtual std::string to_string() const = 0;
};

class PlusOperator : public BinaryOperator {
public:
  using BinaryOperator::BinaryOperator;
  virtual int evaluate() const {
    return leftOperand.evaluate() + rightOperand.evaluate();
  }
  virtual std::string to_string() const {
    return "(" + leftOperand.to_string() + "+" + rightOperand.to_string() + ")";
  }
};

还有这个主要功能

int main(void) {
  Constant c1{5}, c2{10};
  PlusOperator p1{c1, c2};
  std::cout << p1.to_string() << " = " << p1.evaluate() << std::endl;

  PlusOperator p2{Constant{5}, Constant{10}};
  std::cout << p2.to_string() << " = " << p2.evaluate() << std::endl; // (1)
}

编译过程中没有问题(g++ -std=c++17)。但是,如果我使用 -fsanitize=address 标志进行编译,程序会在点 (1) 处死掉。当我想打电话给p2.to_string()时,根据gdb。我假设,我在 (2) 处做错了,并且对象未正确存储/寿命延长。

所以我的具体问题是:如何将临时对象绑定到我的 Expression-Ref 而不会导致地址清理程序失败?有什么替代品?

提前致谢!

【问题讨论】:

    标签: c++ c++17 rvalue-reference


    【解决方案1】:

    所以我的具体问题是:如何将临时对象绑定到我的 Expression-Ref 而不会导致地址清理程序失败?

    你不能。临时对象在完整表达式结束时被销毁,除非您使用对 const 的函数本地引用或函数本地右值引用来捕获它们。您的类成员不是对 const 的函数本地引用或函数本地右值引用,因此没有临时生命周期延长。

    【讨论】:

    • 那么我的班级成员必须是什么类型的?
    • @nicksheen 既然你使用多态,我建议std::unique_ptr&lt;Expression&gt;
    • BinaryOperator(const Expression&amp; left, const Expression&amp; right) : leftOperand{std::make_unique&lt;Expression&gt;(left)}, rightOperand{std::make_unique&lt;Expression&gt;(right)} {} 无法编译:invalid new-expression of abstract class type ‘Expression’
    猜你喜欢
    • 2014-10-31
    • 2017-12-06
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    • 1970-01-01
    • 2018-09-30
    相关资源
    最近更新 更多