I have a class that generalizes SISO functions:
template<typename T, typename S> struct Function {
virtual S operator()(const T& value) const = 0;
Then I have a bunch of subclasses of a BinaryOperator class:
template<typename T, typename S> struct BinaryOp : public Function<T, S> {
Function<T, S>& funcA;
Function<T, S>& funcB;
...
}
template<typename T, typename S> struct Addition : public BinaryOp<T, S> {
virtual inline S operator()(const T& value) const {
return funcA(value) + funcB(value);
}
};
After these I can finally implement the operators used to add, multiply, etc. the functions together. So these build an AST, memory management for later.
inline Addition<T, S>& operator+(Function<T, S>& func) {
return *new Addition<T, S>(*this, func);
}
inline Addition<T, S>& operator+(const T& ref) {
return *new Addition<T, S>(*this, *new Const<T>(ref));
}
...
I also implement common functions (sine, cosine, etc.):
template<typename T> struct Sine : public Function<T, T> {
virtual inline T operator()(const T& value) const {
return std::sin(value);
}
};
The problem appears once I want to implement nested functions [f(g(x))].
template<typename U> inline Inclusion<T, S, U> operator()(Function<U, S>& func) {
return *new Inclusion<T, S, U>(*this, func);
}
I tried to use this operator using this sketch but failed. According to VS it cannot convert Cosine[T = float] to const float&. So it seems like it's trying to use the first implementation of the operator().
Sine<float> sine = Sine<float>();
Cosine<float> cos = Cosine<float>();
Function<float, float>& func = sine(cos);
If I don't use the operator() but give it some random name it works. Can anyone tell me why? Or better how can I make this work while keeping the templates and operator overloading?
The line generating the error:
Function<float, float>& func = sine(cos);
And the errors:
function "System::Math::Sine<T>::operator() [with T=float]" cannot be called with the given argument list, argument types are: (System::Math::Cosine<float>)
object type is: System::Math::Sine<float>
'float System::Math::Sine<float>::operator ()(const T &) const': cannot convert argument 1 from 'System::Math::Cosine<float>' to 'const float &'