Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template template function parameter [duplicate]

For the life of me, I can't get this simple piece of arcane template magic to work:

template<typename T, int a, int b>
int f(T v){
  return v*a-b; // just do something for example
}

template<typename T, int a, int b, template<typename,int,int> class func>
class C{
  int f(){
    return func<T,a,b>(3);
  }
};

int main(){
  C<float,3,2, f> c;
}

Is this possible to do without involving functors?

like image 633
Emily L. Avatar asked Aug 01 '13 11:08

Emily L.


Video Answer


2 Answers

f is supposed to be a class - you have a function.

See below:

// Class acts like a function - also known as functor.
template<typename T, int a, int b>
class f
{
  int operator()(T v)
  {
    return v*a-b; // just do something for example
  }
};

template<typename T, int a, int b, template<typename,int,int> class func>
class C
{
  int f()
  {
    return func<T,a,b>(3);
  }
};

int main()
{
  C<float,3,2, f> c;
}

... And the adapted version if you need to port legacy code (Adapts the function to a class template):

#include <iostream>


template<typename T, int a, int b>
int f(T v)
{
  std::cout << "Called" << std::endl;
  return v*a-b; // just do something for example
}

template<typename T, int a, int b, template<typename,int,int> class func>
struct C
{
  int f()
  {
    return func<T,a,b>(3);
  }
};

template <class T, int a, int b>
struct FuncAdapt
{
  T x_;
  template <class U>
  FuncAdapt( U x )
  : x_( x )
  {}
  operator int() const
  {
    return f<T,a,b>( x_ );
  }
};

int main()
{
  C<float,3,2, FuncAdapt > c;
  c.f();
}
like image 96
Werner Erasmus Avatar answered Oct 20 '22 13:10

Werner Erasmus


You can solve it through a little trickery:

template<typename T, int a, int b>
int f(T v){
  return v*a-b; // just do something for example
}

template<typename T, int, int>
using func_t = int (*)(T);

template<typename T, int a, int b, func_t<T, a, b> func>
class C{
  int f(){
    return func(3);
  }
};

C<float,3,2, f<float, 3, 2>> c;

First you need a type-alias for the function (func_t above), and you unfortunately need to duplicate the template arguments in the declaration of c.

like image 20
Some programmer dude Avatar answered Oct 20 '22 12:10

Some programmer dude