检测类型是否为std :: tuple?

Vin*_*ent 13 c++ templates tuples type-traits c++11

目前我有两个功能:

template<typename Type> bool f(Type* x);
template<typename... List> bool f(std::tuple<List...>* x);
Run Code Online (Sandbox Code Playgroud)

有没有办法将这两个函数与一个额外的模板参数合并,该参数指示传递的类型是否为元组?

template<typename Type, bool IsTuple = /* SOMETHING */> bool f(Type* x);
Run Code Online (Sandbox Code Playgroud)

Xeo*_*Xeo 13

当然,使用is_specialization_of(链接从这里采取和修复):

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

但问题是,你真的想要吗?通常,如果您需要知道类型是否为元组,则需要对元组进行特殊处理,这通常与其模板参数有关.因此,您可能希望坚持使用重载版本.

编辑:既然你提到你只需要一小部分专业,我建议重载但只适用于小特殊部分:

template<class T>
bool f(T* x){
  // common parts...
  f_special_part(x);
  // common parts...
}
Run Code Online (Sandbox Code Playgroud)

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 */ }
Run Code Online (Sandbox Code Playgroud)

  • `static if`,我们需要yooooooou (5认同)
  • 在 C++ 17 中,您可以使用 `constexpr if` (2认同)

sma*_*c89 7

在C ++ 17中,这是一个相当简单的解决方案,使用 if constexpr

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

template <typename ...T> struct is_tuple<std::tuple<T...>>: std::true_type {};
Run Code Online (Sandbox Code Playgroud)

然后,您可以执行以下操作:

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;
}
Run Code Online (Sandbox Code Playgroud)

确保其有效的测试:

f(&some_tuple);
f(&some_object);
Run Code Online (Sandbox Code Playgroud)

输出:

一个元组!
不是元组


解决方案部分取自以下答案如何知道类型是否为std :: vector的特化?


Vau*_*ato 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); }
Run Code Online (Sandbox Code Playgroud)


Dav*_*son 5

对于C ++ 11,这是我的首选模式:

// IsTuple<T>()
template <typename T>
struct IsTupleImpl : std::false_type {};

template <typename... U>
struct IsTupleImpl<std::tuple <U...>> : std::true_type {};

template <typename T>
constexpr bool IsTuple() {
  return IsTupleImpl<decay_t<T>>::value;
}
Run Code Online (Sandbox Code Playgroud)

效果很好。没有依赖关系(我不能使用Boost)。