将右值引用绑定到左值引用 class 成员
Bind rvalue ref to lvalue ref class member
我有以下定义
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) 处做错了,对象没有正确 stored/lifetime 扩展。
所以我的具体问题是:如何将临时对象绑定到我的 Expression-Ref 而不会使地址清理器失败?什么是替代品?
提前致谢!
So my concrete question is: how is it possible to bind a temporary object to my Expression-Ref without failing the address-sanitizer?
你不能。临时对象在完整表达式的末尾被销毁,除非您使用对 const 的函数局部引用或函数局部右值引用来捕获它们。您 class 成员不是对 const 的函数局部引用或函数局部右值引用,因此没有临时生命周期延长。
我有以下定义
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) 处做错了,对象没有正确 stored/lifetime 扩展。
所以我的具体问题是:如何将临时对象绑定到我的 Expression-Ref 而不会使地址清理器失败?什么是替代品?
提前致谢!
So my concrete question is: how is it possible to bind a temporary object to my Expression-Ref without failing the address-sanitizer?
你不能。临时对象在完整表达式的末尾被销毁,除非您使用对 const 的函数局部引用或函数局部右值引用来捕获它们。您 class 成员不是对 const 的函数局部引用或函数局部右值引用,因此没有临时生命周期延长。