0

In a template class with two template parameters T and U, I'd like to define an alias which is the tuple {T,U} if U is not itself a tuple (T is never a tuple) or the tuple {T,U0,...,Un} if U is the tuple {U0,...,Un}. I tried the following which did not compiled (for non-tuple U):

#include <type_traits>
#include <tuple>

//!
//! Template to check whether a type is a tuple.
//! From : https://stackoverflow.com/questions/13101061/detect-if-a-type-is-a-stdtuple
//!
template <typename T>
constexpr bool IsTuple = false;
template<typename ... types>
constexpr bool IsTuple<std::tuple<types...>> = true;

template<typename T, typename U>
class A
{
using TU = typename std::conditional<IsTuple<U>, decltype(std::tuple_cat(std::declval<std::tuple<T>>(), std::declval<U>())), std::tuple<T,U>>::type;

TU myTuple;

public:
 A() = default;
};

int main()
{
A<int,int> a; //  Fails compiling
              //  Would compile with A<int,std::tuple<int>>
} 

which fails compiling because both types in std::conditional must exist while tuple_cat cannot handle (std::tuple<int>, int>).

Is there any simple way to achieve this ?

Gautier
  • 3
  • 2

1 Answers1

1

Something along these lines perhaps:

template<typename T, typename U>
class A {

  template <typename X, typename Y>
  static std::tuple<X, Y> Helper(Y&&);

  template <typename X, typename ... Elems>
  static std::tuple<X, Elems...> Helper(std::tuple<Elems...>&&);


  using TU = decltype(Helper<T>(std::declval<U>()));
};
Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85