2013-08-01 133 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

我想避免模板參數的重複,這應該可以節省我在單元測試中輸入/複製粘貼很多東西。從這個公寓,這是迄今爲止最好的答案。 –