In C++ I have a tuple with some elements in it:
std::tuple my_tuple(3, \'q\');
And some template function that perfectly
n
being a runtime value, it can't be used to instanciate a template at compile-time. Your switch
works because you manually instanciate each std::get
, and wire them to the corresponding runtime value.
But yeah, it's a bit of a chore to write that braindead switch
tree. Why not let the compiler generate the boilerplate with a bit of TMP ?
#include
#include
#include
template
void my_function(T);
// Test specialisations to see what's going on
template <> void my_function(int i) { std::cout << "int " << i << '\n'; }
template <> void my_function(char c) { std::cout << "char " << c << '\n'; }
namespace detail {
// Available in std in C++14
template
using enable_if_t = typename std::enable_if::type;
// Mockup function signature to pick up the call when enable_if shunts
template
void callMyFunc(T&&, ...) {
assert(!"Index not in range !");
}
// "Simple" recursive solution, removes itself from the overload set
// to stop recursion
template >
void callMyFunc(std::tuple &tuple, std::size_t n) {
return n == N
? my_function(std::get(tuple))
: callMyFunc(tuple, n);
}
}
// Tiny user-friendly wrapper
template
void callMyFunc(std::tuple &tuple, std::size_t n) {
detail::callMyFunc<0u>(tuple, n);
}
int main(int, char**) {
std::tuple my_tuple(3, 'q');
// Success.
callMyFunc(my_tuple, 0u);
callMyFunc(my_tuple, 1u);
return 0;
}