模板模板函数参数

时间:2013-08-01 11:06:51

标签: c++ template-meta-programming template-templates

对于我的生活,我无法让这个简单的奥术模板魔法工作:

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;
}

这可以不涉及仿函数吗?

4 个答案:

答案 0 :(得分:7)

f应该是一个类 - 你有一个函数。

见下文:

// 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;
}

...如果你需要移植遗留代码,那么改编版本(将函数改编为类模板):

#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();
}

答案 1 :(得分:7)

你可以通过一点点诡计来解决它:

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;

首先你需要一个函数的类型别名(上面是func_t),遗憾的是你需要在c的声明中复制模板参数。

答案 2 :(得分:0)

您的编译器抱怨的原因是您将函数(f)作为类传递给类C的最后一个模板参数。

由于无法将函数作为模板参数传递,因此应使用函数指针或仿函数。而仿函数绝对是更清洁的方法。

所以,虽然可以在不使用仿函数的情况下达到你想要的效果,但你真的不应该尝试。

如果你想使用函数指针,你会看到这样的东西:

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

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

在这种情况下,我认为您无法消除c声明中的代码重复,但我可能错了。

答案 3 :(得分:-1)

不,不是。甚至语法:

template <typename T, int a, int b, template <typename, int, int> class func>
                                                                  ^^^^^

表明模板模板参数的参数必须是类模板。