Search code examples
c++templatesc++17variadic-templates

When using variadric template, how to get nth arguments type?


I want to have a class that holds n values, much like std::tuple. I can't quite use tuple though, as there is additional logic in obtaining the values - they are on demand.

Please consider this class I wrote as an example:

// somewhere else
template<typename TVal>
TVal valueGetter() { ... };

template<typename ...TColValue>
class ResultRow
{
public:
  template<unsigned int TIndex>
  get_nth_from_variadric<TIndex, TColValue> GetValue() const
  {
    return valueGetter<get_nth_from_variadric<TIndex, TColValue> >();
  }
  

};

What I want it to work like is that the user simply calls int myVal = GetValue<1>, given class template params ResultRow<bool, int>. For this to work, I need to be able to convert the index of the template argument into type.

How can I do that?


Solution

  • You can get the type from parameter pack with the help of a recursive inheriting type trait.

    template<unsigned int TIndex, typename ...TColValue>
    struct get_nth_from_variadric_type;
    
    template<unsigned int TIndex, typename Head, typename... Tail >
    struct get_nth_from_variadric_type<TIndex, Head, Tail...>
        : get_nth_from_variadric_type<TIndex-1, Tail...> { };
    
    template<typename Head, typename... Tail>
    struct get_nth_from_variadric_type<0, Head, Tail...> {
       using type = Head;
    };
    
    template<unsigned int TIndex, typename ...TColValue>
    using get_nth_from_variadric = typename get_nth_from_variadric_type<TIndex, TColValue...>::type;
    

    Then use it like

    template<typename ...TColValue>
    class ResultRow
    {
    public:
      template<unsigned int TIndex>
      get_nth_from_variadric<TIndex, TColValue...> GetValue() const
      {
        return valueGetter<get_nth_from_variadric<TIndex, TColValue...> >();
      }
    };