2013-09-25 133 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

相關問題