12

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

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

4 回答 4

8

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();
}
于 2013-08-01T11:17:14.527 回答
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.

于 2013-08-01T11:22:38.030 回答
0

不,这不对。甚至语法:

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

表明模板模板形参的实参必须是类模板。

于 2013-08-01T11:12:03.303 回答
0

您的编译器抱怨的原因是您将函数 ( f) 作为类传递给 class 的最后一个模板参数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,但我可能错了。

于 2013-08-01T11:20:03.260 回答