Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if a type is a std::tuple?

Currently I have two functions :

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

Is there any way to merge these two functions with an extra template parameter that indicates whether the passed type is a tuple ?

template<typename Type, bool IsTuple = /* SOMETHING */> bool f(Type* x);
like image 258
Vincent Avatar asked Oct 27 '12 14:10

Vincent


People also ask

What is a std :: tuple?

Class template std::tuple is a fixed-size collection of heterogeneous values. It is a generalization of std::pair.

Is tuple a Constexpr?

Initializes each element of the tuple with the corresponding element of other . This constructor is constexpr if every operation it performs is constexpr. For the empty tuple std::tuple<>, it is constexpr.

Is there tuple in C++?

Tuples in C++A tuple is an object that can hold a number of elements. The elements can be of different data types. The elements of tuples are initialized as arguments in order in which they will be accessed. 1.

Is tuple mutable in C++?

The tuple itself isn't mutable (i.e. it doesn't have any methods that for changing its contents). Likewise, the string is immutable because strings don't have any mutating methods. The list object does have mutating methods, so it can be changed.


2 Answers

Sure, using is_specialization_of (link taken and fixed from here):

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

The question is, however, do you really want that? Normally, if you need to know if a type is a tuple, you need special handling for tuples, and that usually has to do with its template arguments. As such, you might want to stick to your overloaded version.

Edit: Since you mentioned you only need a small portion specialized, I recommend overloading but only for the small special part:

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

with

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 */ }
like image 156
Xeo Avatar answered Oct 12 '22 00:10

Xeo


With C++17, here is a fairly simple solution using if constexpr

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

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

Then you can do something like:

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

A test to ensure it worked:

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

Output:

A tuple!!
Not a tuple


Solution taken in part from an answer found here: How to know if a type is a specialization of std::vector?

like image 34
smac89 Avatar answered Oct 12 '22 01:10

smac89