2012-10-27 56 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?

相关问题