У меня есть рекурсивный класс Expression
, обозначающие булевы подобные выражения, например:C++ оператора перегрузки в рекурсивных выражениях классов
(a & b) | (c & ~d)
Обратите внимание, что Expression
заботится как одинарных и двойных выражений. В принципе, Expression
должен следовать за CFG, подобным логическому выражению.
Я разработал класс следующим образом:
class Expression {
public:
Expression() = default;
Expression(unique_ptr<Expression> lhs, unique_ptr<Expression> rhs,
unique_ptr<IBinaryOperator> binop, unique_ptr<IUnaryOperator> unop);
Expression operator^(Expression& that);
Expression operator%(Expression& that);
Expression operator|(Expression& that);
Expression operator*(Expression& that);
Expression operator+(Expression& that);
Expression operator&(Expression& that);
Expression operator>>(Expression& that);
Expression operator!();
Expression operator~();
double Evaluate(double x);
virtual ~Expression();
protected:
unique_ptr<Expression> _lhs = nullptr;
unique_ptr<Expression> _rhs = nullptr;
unique_ptr<IBinaryOperator> _binop = nullptr;
unique_ptr<IUnaryOperator> _unop = nullptr;
};
Реализация конструктора и по одному из бинарных и унарных операторов приведены ниже:
Expression::Expression(unique_ptr<Expression> lhs, unique_ptr<Expression> rhs, unique_ptr<IBinaryOperator> binop, unique_ptr<IUnaryOperator> unop) :
_lhs(move(lhs)), _rhs(move(rhs)), _binop(move(binop)), _unop(move(unop)) {
}
Expression Expression::operator+(Expression&& that) {
return Expression(unique_ptr<Expression>(this), unique_ptr<Expression>(&that), unique_ptr<IBinaryOperator>(new SumCoNorm), nullptr);
}
Expression Expression::operator~() {
return Expression(nullptr, unique_ptr<Expression>(this), nullptr, unique_ptr<IUnaryOperator>(new Intensify));
}
Класс не может скомпилировать с
error: use of deleted function 'Fuzzy::Expression::Expression(const Fuzzy::Expression&)'
в каждом перегруженных операторов (в операторах return). Я чувствую, что какая-то функция внутренне пытается использовать конструктор копирования unique_ptr, которого не существует. Я что-то делаю с движущимися указателями здесь и там? Я использую C++ 11 с GCCv4.8.
Предложения по изменениям в интерфейсе классов приветствуются. Я бы предпочел избегать использования исходных указателей.
Примечание: Пожалуйста, не предлагайте использовать генератор парсера или подобное, например Boost.Spirit, YARD или YACC. Приложение требует от меня реализовать это с нуля.
Я признаю, что я ржавый, но мне кажется странным, что вы перемещаете аргументы своего конструктора в члены данных объекта. – Richard
Nevermind; теперь я вижу, что это локальные 'unique_ptr <>. Я ожидал, что они будут ссылками. – Richard