Consider the following code:
struct Base
{
~Base() {}
virtual double operator()(double x) const = 0;
};
template<typename F, typename G> struct Compose; //forward declaration of Compose
struct Derived1 : public Base //plus many more derived classes
{
virtual double operator()(double x) const {return x;}
template <typename F>
Compose<Derived1,F> operator()(const F& f) const {return Compose<Derived1,F>(*this,f);}
};
template<typename F, typename G>
struct Compose : public Base
{
Compose(const F &_f, const G &_g) : f(_f), g(_g) {}
F f;
G g;
virtual double operator()(double x) const {return f(g(x));}
};
void test()
{
Derived1 f,g;
auto h=f(g);
}
The class compose here takes two derived classes f,g and returns the compositum f(g(x)) via operator().
Is it somehow possible to avoid the explicit definition in each of the many derived classes, and add a function in the base class?
EDIT: To explain better what I am looking for: In principle, I want to add something like the following in the base class
template<typename F> Compose<decltype(*this), F>
operator()(const F& f) {return Compose<decltype(*this), F>(*this,f);}
I tried this in the hope that decltype(*this) automatically inserts the type of the derived class. But it doesn't seem to work like this...
Solution: I finally encountered the way to do it, and that is via CRTP. The Base class then takes the form
template<typename Derived>
struct Base
{
~Base() {}
virtual double operator()(double x) const = 0;
template<typename F> Compose<Derived, F>
operator()(const F& f) {return Compose<Derived, F>(static_cast<Derived const&>(*this),f);}
};
and the derived classes are derived from
struct Derived1 : public Base<Derived1>