So I'm trying to write an algorithmic derivator, to derivate/evaluate simple polynomials. My Expression Logic is as follows: there are Constants and Variables, combined in to either a multiply or add Expression. In my Expression Class i have the method derivative which should return different Expressions depending wheter the Expression is an add or a multiply. here is my code:
enum OP_enum {Add, Multiply};
//********
template<typename T>
class Constant {
public:
Constant(const T & v) : val_(v) {}
T operator()(const T &) const {
return val_;
}
Constant<T> derivative(){
return Constant<T>(0);
}
private:
T val_;
};
//********
template <typename T>
class Variable {
public:
T operator()(const T & x) const {
return x;
}
Constant<T> derivative(){
return constant(1);
}
};
//********
template<typename L, typename R, OP_enum op>
class Expression {
public:
Expression(const L & l, const R & r) : l_(l), r_(r) { }
template <typename T>
T operator()(const T & x) const {
switch (op) {
case Add:
return l_(x) + r_(x);
case Multiply:
return l_(x) * r_(x);
}
}
/*RETURN TYPE*/ derivative() {
switch (op) {
case Add:
return l_.derivative() + r_.derivative();
case Multiply:
return l_.derivative() * r_ + l_ * r_.derivative();
}
}
private:
L l_;
R r_;
};
//********
template<typename L, typename R>
Expression<L, R, Add> operator*(const L & l, const R & r) {
return Expression<L, R, Add>(l, r);
}
template<typename L, typename R>
Expression<L, R, Multiply> operator+(const L & l, const R & r) {
return Expression<L, R, Multiply>(l, r);
}
is there a way i can specify the RETURN TYPE nicely? (it should be
Expression<RETURN TYPE of derivation called on L, RETURN TYPE of derivation called on R, Add>
Expression<Expression<RETURN TYPE of derivation called on L, R, Multiply>, Expression<L, RETURN TYPE of derivation called on R, Multiply>, Add>
depending if a sum or product is beeing derivated)
i have tried std::conditional and several things with decltype
auto derivative() {
if constexpr (op == Ad)
return l_.derivative() + r_.derivative();
else if constexpr (op == Multiply)
return l_.derivative() * r_ + l_ * r_.derivative();
}
The if constexpr
is required if the branches deduce to different types.