I have a recursive class Expression
which denotes boolean-like expressions, for instance:
(a & b) | (c & ~d)
Note that Expression
takes care of both unary and binary expressions.
Basically, Expression
should follow the CFG similar to a boolean expression.
I have designed the class in this way:
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;
};
The implementation of the constructor and one each of the binary and unary operators are shown below:
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));
}
The class fails to compile with
error: use of deleted function 'Fuzzy::Expression::Expression(const Fuzzy::Expression&)'
in each of the overloaded operators (in the return statements). I get the feel that some function is internally trying to use the copy constructor of unique_ptr, which does not exist. Am I doing something wrong with moving pointers here and there? I am using C++11 with GCCv4.8.
Suggestions to changes in class interface in any way is welcome. I would prefer avoiding the use of raw pointers.
Note: Please do not suggest using a parser generator or the like, such as Boost.Spirit, YARD or YACC. The application requires me to implement this from scratch.