对于我的生活,我无法让这个简单的奥术模板魔法工作:
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;
}
这可以不涉及仿函数吗?
答案 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>
^^^^^
表明模板模板参数的参数必须是类模板。