Easiest way to get the N-th argument of a variadic templated class?

Viewed 5459

I wonder what is the easiest and more common way to get the N-th parameter of a variadic templated class at compile-time (The returned value has to be as a static const for the compiler in order to do some optimizations). Here is the form of my templated class :

template<unsigned int... T> MyClass
{
    // Compile-time function to get the N-th value of the variadic template ?
};

Thank you very much.

EDIT : As MyClass will contain more than 200 functions, I can't specialize it. But I can specialize a struct or a function inside MyClass.

EDIT : Final solution derived from the validated answer :

#include <iostream>

template<unsigned int... TN> class MyClass
{
    // Helper
    template<unsigned int index, unsigned int... remPack> struct getVal;
    template<unsigned int index, unsigned int In, unsigned int... remPack> struct getVal<index, In,remPack...>
    {
        static const unsigned int val = getVal<index-1, remPack...>::val;
    };
    template<unsigned int In, unsigned int...remPack> struct getVal<1,In,remPack...>
    {
        static const unsigned int val = In;
    };

    // Compile-time validation test
    public:
        template<unsigned int T> inline void f() {std::cout<<"Hello, my value is "<<T<<std::endl;}
        inline void ftest() {f<getVal<4,TN...>::val>();} // <- If this compile, all is OK at compile-time
};
int main()
{
    MyClass<10, 11, 12, 13, 14> x;
    x.ftest();
    return 0;
}
4 Answers

Yet another simple method:

#include <array>

template<int... Args>
class Foo {
 public:
  static constexpr int Element(int index) {
    return std::array<int, sizeof...(Args)>{ Args... }[index];
  }

 int First = Element(0);
 int Second = Element(1);
};


int main() {
  return Foo<0, 1>::Element(0);  
}

// or just
int Nth = std::array<int, sizeof...(Args)>{ Args... }[N];

BTW, here is a general method of extracting N-th argument of any variadic template:

#include <tuple>

template<typename... Args>
class Foo {
 public:
  template <int N>
  using Nth = typename std::remove_reference<decltype(std::get<N>(std::declval<std::tuple<Args...>>()))>::type;
};


int main() {
  Foo<int, float>::Nth<1> val = 3.14159f;
  return 0; 
}
Related