2013-08-01 102 views
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 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

你究竟想达到什么目的? – nijansen

+0

我的编译器在执行这段代码时崩溃了。 – Saksham

+0

@nijansen是不是MSVS2010稳定? – Saksham

回答

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

恭喜你的第一分 – Saksham

+0

谢谢。我看到我需要一个声望来鼓励某人......因此我回答了一个问题。 –

+0

OP没有使用仿函数就不想要它吗? (引用:“这可能不涉及仿函数吗?”) –

-1

不,事实并非如此。甚至语法:

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

显示模板模板参数的参数必须是类模板。

+0

是的,我知道,我正在寻找一些欺骗手段,以避免更改我的生产代码,使单元测试代码更加整洁。 –

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声明的代码重复,但我可能是错的。

6

你可以通过一个小诡计解决这个问题:

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声明。

+1

...在C++ 11中,如果你的编译器支持模板别名的话。 MSVC 2013 *仍*不 – SteveLove

+0

我想避免模板参数的重复,这应该可以节省我在单元测试中输入/复制粘贴很多东西。从这个公寓,这是迄今为止最好的答案。 –