C++ – Access tuple element in C++11 via compile time variable in function

c++c++11stdtuple

The following minimal example compiles with g++ -std=c++11 -Wall tuple.cpp -o tuple:

#include <tuple>
#include <iostream>

template<int i>
char get_elem_i(std::tuple<char, char> t)
{
    return std::get<i>(t);
}

int main()
{
    std::tuple<char, char> t('H','i');
    char c = get_elem_i<0>(t);
    std::cout << "The char is: " << c << std::endl;
}

Now, I do not want to use a template which specifies the index (the exact reason why: I have templates that are deduced automatically, and I do not want to need to specify them all). So my first try was:

char get_elem_i(int i, std::tuple<char, char> t)
{
    return std::get<i>(t);
}

I understand that this can not compile. Is there any way to assure the compiler that i will be known at compile time? Maybe something like this?

char get_elem_i(compile_time_known int i, std::tuple<char, char> t)

Best Solution

You could use a std::array instead of a std::tuple. In the example given, the members of the tuple all have the same type.

So, we could do:

char get_elem_i(int i, std::array<char, 2> t)
{
    return t[i];
}

Here's a slight variant on the example you gave to show why it's not directly possible in the general case:

???? get_elem_i(int i, std::tuple<char, struct foo, class bar> t) {
    return std::get<i>(t);
}

What is the return type of that function? char? struct foo?


And you could always write a function like this:

char get_elem_i(int i, std::tuple<char, char> t) {
    switch (i) {
        case 0: return std::get<0>(t);
        case 1: return std::get<1>(t);
    }

    assert(false);
}
Related Question