2016-02-26 86 views
1

比方說,我們有3種類型(S1,S2和S3):如何使用可變模板轉發類型和值模板參數?

//type 1 (good type) 
template<typename T1, typename T2, typename T3> 
struct S1{}; 

//type 2 (good type) 
template<typename T1, typename T2, typename T3, int T4> 
struct S2{}; 

//type 3 (bad type) 
template<typename T1, typename T2, typename T3> 
struct S3{}; 

//any other type is also a "bad type" 

我們想創造一種特質,以確定是否類型是S1或S2。
爲了簡便起見,我們使用可變參數模板,爲T#細節不是很重要:

//a type trait to determine if a type is either "type 1" or "type 2" 
//We expect ::value to be true if we can match either type. 
//false otherwise. 
//*ignore cv-qualifier related details 
template <typename T>  struct test:std::false_type{}; 
template <typename... Args> struct test<S1<Args...>>:std::true_type{}; 
template <typename... Args> struct test<S2<Args...>>:std::true_type{}; 

如果我們來測試這種類型的特點,我們可以看到,它並不適用於S2工作:

std::cout << std::boolalpha; 
    std::cout << test<S1<int,int,int>>::value << '\n'; 
    std::cout << test<S2<int,int,int,5>>::value << '\n'; 
    std::cout << test<S3<int,int,int>>::value << '\n'; 

打印:

true 
false 
false 

它不會對S2工作,因爲模板類型中的一種已經定義了(在這種情況下,T4已經是一個int)。

是否可以使用可變模板來匹配所有模板類型?
無論它們是類型名稱還是實際類型。

回答

4
template <class A0,class A1, class A2, int x> struct test<S2<A0,A1,A2,x>>:std::true_type{}; 

一般來說,帶有非類型模板參數的元元編程是一個痛苦。

考慮使用像integral_constant之類的東西,如果你做了很多它:將值作爲類型而不是值傳遞。你甚至可以將模板作爲類型傳遞。

1

這裏是一個解決方案,讓您需要的輸出,而無需重新設計你的S2:

#include <iostream> 
#include <type_traits> 

template<typename T1, typename T2, typename T3> 
struct S1{}; 

//type 2 (good type) 
template<typename T1, typename T2, typename T3, int T4> 
struct S2{}; 

//type 3 (bad type) 
template<typename T1, typename T2, typename T3> 
struct S3{}; 

template <typename T>  struct test : std::false_type{}; 
template <typename... Args> struct test<S1<Args...>> : std::true_type{}; 

template <template <typename, typename, typename, int> class P, typename A, typename B, typename C, int N> 
struct test<P<A,B,C,N>> : std::conditional< 
    std::is_same<P<A,B,C,N>, S2<A,B,C,N>>::value, 
    std::true_type, 
    std::false_type 
>::type {}; 

template <typename T1, typename T2, typename T3, int T4> struct S2Wannabe {}; 

int main() { 
    std::cout << std::boolalpha; 
    std::cout << test<S1<int,int,int>>::value << '\n'; // true 
    std::cout << test<S2<int,int,int,5>>::value << '\n'; // true 
    std::cout << test<S3<int,int,int>>::value << '\n'; // false 
    std::cout << test<S2Wannabe<int,int,int,5>>::value << '\n'; // false 
} 

但重新設計S2可以更容易地解決你的問題。

相關問題