目前我有兩個功能:檢測一個類型是一個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);
目前我有兩個功能:檢測一個類型是一個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);
當然,使用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 */ }
你可能只是有你函數推遲到另一個函數:
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); }
用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?
在正常時間,這可能是危險的,專業化將是可取的。但是這個函數是一個很大的函數,只有一個小的'if'裏面會改變元組的類型與否。 – Vincent
使用額外的模板參數還意味着可以顯式調用'f,false>'或'f ',這可以通過檢查函數體中的'is_specialization_of'來避免。 –
hvd
@Vincent:那我實際上推薦標籤分派而不是運行時if。 :) – Xeo