2012-10-27 57 views
10

目前我有兩個功能:檢測一個類型是一個std ::元組嗎?

template<typename Type> bool f(Type* x); 
template<typename... List> bool f(std::tuple<List...>* x); 

有什麼辦法來合併這兩個功能一個額外的模板參數,指示傳遞類型是否是一個元組?

template<typename Type, bool IsTuple = /* SOMETHING */> bool f(Type* x); 

回答

10

當然,使用is_specialization_of(從here採取固定鏈接):

template<typename Type, bool IsTuple = is_specialization_of<Type, std::tuple>::value> 
bool f(Type* x); 

問題是,但是,你真的想要嗎?通常,如果你需要知道一個類型是否是一個元組,你需要對元組進行特殊處理,而這通常與其模板參數有關。因此,你可能想堅持你的超載版本。

編輯:既然你提到你只需要一小部分專業,我建議重載但只適用於小的特殊組成部分:

template<class T> 
bool f(T* x){ 
    // common parts... 
    f_special_part(x); 
    // common parts... 
} 

template<class T> 
void f_special_part(T* x){ /* general case */ } 

template<class... Args> 
void f_special_part(std::tuple<Args...>* x){ /* special tuple case */ } 
+0

在正常時間,這可能是危險的,專業化將是可取的。但是這個函數是一個很大的函數,只有一個小的'if'裏面會改變元組的類型與否。 – Vincent

+0

使用額外的模板參數還意味着可以顯式調用'f ,false>'或'f ',這可以通過檢查函數體中的'is_specialization_of'來避免。 – hvd

+0

@Vincent:那我實際上推薦標籤分派而不是運行時if。 :) – Xeo

5

你可能只是有你函數推遲到另一個函數:

template<typename Type,bool IsTuple> bool f(Type *x); 

template<typename Type> 
inline bool f(Type* x) { return f<Type,false>(x); } 

template<typename... List> 
inline bool f(std::tuple<List...>* x) { return f<std::tuple<List...>,true>(x); } 
1

用C++ 17,這裏是用if constexpr

template <typename> struct is_tuple: std::false_type {}; 

template <typename ...T> struct is_tuple<std::tuple<T...>>: std::true_type {}; 

然後,你可以這樣做一個相當簡單的解決方案:

template<typename Type> bool f(Type* x) { 
    if constexpr (is_tuple<Type>::value) { 
     std::cout << "A tuple!!\n"; 
     return true; 
    } 

    std::cout << "Not a tuple\n"; 
    return false; 
} 

的測試,以確保它的工作:

f(&some_tuple); 
f(&some_object); 

輸出:

元組!!從這裏發現了一個answer部分採取
不是一個元組


解決方法:How to know if a type is a specialization of std::vector?

相關問題