template<class T, template<class> class Functor>
class FunctorInterface_1 {
private:
const Functor<T> &f_cref;
public:
FunctorInterface_1() : f_cref(static_cast<const Functor<T>&>(*this)) {}
T operator() ( T val ) const { return f_cref(val); }
}; // FunctorInterface_1 (works)
// Declare a traits class.
template <typename T> struct FunctorTraits;
template<class Functor>
class FunctorInterface_2 {
private:
const Functor &f_cref;
public:
// Use the traits class to define Ftype
using Ftype = typename FunctorTraits<Functor>::type;
FunctorInterface_2() : f_cref(static_cast<const Functor&>(*this)) {}
Ftype operator() ( Ftype val ) const { return f_cref(val); }
}; // FunctorInterface_2 (no type in Functor!)
// Forward declare Cube to specialize FunctorTraits
template<class T> struct Cube;
// Specialize FunctorTraits for Cube
template <typename T> struct FunctorTraits<Cube<T>>
{
using type = T;
};
template<class T>
struct Cube : public FunctorInterface_2<Cube<T>> {
using type = T;
T operator() ( T val ) const { return val*val*val; }
}; // Cube
int main()
{
Cube<int> a;
}