Определить, является ли тип std:: tuple?

В настоящее время у меня есть две функции:

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);

Ответ 1

Конечно, используя is_specialization_of (ссылка взята и исправлена ​​из здесь):

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 */ }

Ответ 2

Вы можете просто отложить функции до другой функции:

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); }

Ответ 3

С С++ 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);

Вывод:

Кортеж!
Не кортеж


Решение, принятое частично из ответа , найденного здесь: Как узнать, является ли тип специализацией std::vector?