2013-09-25 221 views
6

是否可以使用通用函数指针作为模板参数?函数指针模板可以接受自由函数,成员函数和lambda函数。为简单起见,假设该功能只有一个参数,像如何使用通用函数指针作为模板参数?

template<class ArgumentT, class ReturnT, function* f> 
struct A 
{ 
    // f is used somewhere. 
}; 
+0

您可以这样做,但不同的函数类型实例化您将得到不同的不兼容类型。也就是说,即使ArgumentT和ReturnT是相同的,您也不能使用指向成员函数的指针将A的通用函数指针指定给A。 – ComicSansMS

回答

8

一个正常的模板参数可以参考的功能。

#include <iostream> 

template <class ArgT, class RetT, class F> 
struct A { 
    F f; 
public: 
    A(F f) : f(f) {} 

    RetT operator()(ArgT arg) { return f(arg); } 
}; 

int unchanged(int i) { return i; } 

int main(){ 
    A < int, int, int(*)(int)> t{ unchanged }; 

    for (int i = 0; i < 10; i++) 
     std::cout << t(i) << "\n"; 
} 

没有什么限制模板参数的功能,但 - 你可以很容易地使用一些类重载operator(),并援用来代替(事实上,这往往是最好)。

0

你合并类型和数据,你想要的东西更像:

template<class ArgumentT, class ReturnT, typename F*> 
struct A { 
    //use F* to refer to f somewhere 
}; 
+2

这个语法正确吗? – user1899020

0

可以实现的东西亲近:

template<class ArgumentT, class ReturnT, class F, F f> 
struct A; 

template<class ArgumentT, class ReturnT, ReturnT (*f)()> 
struct A<ArgumentT, ReturnT, ReturnT (*)(), f> 
{ 
    // f is used somewhere. 
}; 

template<class ArgumentT, class ReturnT, class C, ReturnT (C::*f)()> 
struct A<ArgumentT, ReturnT, ReturnT (C::*)(), f> 
{ 
    // f is used somewhere. 
}; 

...但你不能拿东西像std::function<ReturnT()>作为非类型模板参数。函数指针的专门化也将接受不捕获的lambdas。

2

我会建议使用std ::函数<>如果你能使用C++ 11或升压::功能<>如果您不能:

template<class ArgumentT, class ReturnT > struct A { 
    typedef std::function< ReturnT(ArgumentT) > Function; 
    void foobar(Function f) { ReturnT ret = f(arg); } 
}; 

在这种情况下,你可以通过函数指针,函子,拉姆达,或使用std :: bind或boost :: bind几乎与签名不匹配的任何函数。我不确定你在这种情况下需要模板,你可以直接使用std :: function,但这取决于你的代码。

+2

但是,使用std :: function有很多缺点,所以这不是全面的建议。 – xaxxon

相关问题