OllieB
OllieB

Reputation: 1431

std::function as template template parameter

Inspired somewhat by this blog, I thought I'd try and create a generalised Functor class in C++. I don't get out much. I'm using it as excuse to properly understand templates, rather than just dabble.

#include <functional>

template<template <typename> typename F_, typename A>
struct Functor {

   template<typename B>
   static F_<B> fmap
      ( std::function<B(A)>
      , F_<A>
      );

};


template<typename A>
struct Functor<std::function, A(void)> {};

template<typename A>
template<typename B>
  std::function<B()> Functor<std::function, A(void)>::fmap
     ( std::function<B(A)> f
     , std::function<A()> fA
     ){
  return [&](){
     return f (fA());
  };
};

After quite a bit of messing about, I'm stumped. I have the compiler error

error: no ‘std::function<B()> Functor<std::function, A()>::fmap(std::function<B(A)>, std::function<A()>)’ member function declared in class ‘Functor<std::function, A()>’

I'm lost. Frankly, I though I had declared this. Any suggestions? I'm compiling using an up to date compiler, gcc 7.2 using C++17. I think C++14 is all that's required though.

Btw, I can quite happily compile a non-general version of fmap

template<typename A, typename B>
std::function<B(void)> fmap1
   ( std::function<B(A)> f
   , std::function<A(void)> fA
   )
{
   return [&](){
      return f (fA());
   };
};

Upvotes: 2

Views: 76

Answers (1)

You partially specialized Functor. And that's okay, but your specialization doesn't declare any members. Specifically, no fmap member. Recall that a specialization doesn't automatically obtain anything from the primary template.

So just add the declaration:

template<typename A>
struct Functor<std::function, A(void)>
{
    template<typename B>
   static std::function<B()> fmap
      ( std::function<B(A)>
      , std::function<A()>
      );
};

Upvotes: 3

Related Questions