How do I use a variable to index into a tuple using std::get<>? I have the following code:
#include
#include
using n
The likely answer that you should adopt is to just use an array, vector, or other kind of indexed container.
In the event that the tuple elements are not homogeneous types and you actually do need an answer for that case, it's a bit complex. This is because types need to be known at compile time. So where you think you could do std::cout << get_from_tuple(a_tuple, index)
for example, this can't work as easily as you think it can because the operator<<
overload for sending the object to the standard output stream is selected at compile time. Obviously, this means that the index must be known at compile time, too -- otherwise we can't know the type of the tuple element.
However, it is possible to build a template function that can, in fact, implement exactly this behavior. The end result, when compiled, is a conditional tree that is capable of handling each element in the tuple, but we enlist the compiler to help us build that conditional tree.
What I will build here is a function that, given a tuple, index, and functor, will invoke the functor, forwarding that particular tuple item, and will then return true. If the index is out of range, it will return false.
If the functor is not able to be called with every element in the tuple, the template function will fail to instantiate.
The final solution looks like this:
#include
#include
namespace detail {
template
struct size_wrapper { };
template
bool visit_tuple_index_impl(Tup && t, std::size_t index, V && visitor, size_wrapper)
{
if (index == I - 1) {
visitor(std::get(std::forward(t)));
return true;
}
return visit_tuple_index_impl(std::forward(t), index, visitor, size_wrapper());
}
template
bool visit_tuple_index_impl(Tup &&, std::size_t, V &&, size_wrapper<0>)
{
return false;
}
}
template
bool visit_tuple_index(Tup && t, std::size_t index, V && visitor)
{
return detail::visit_tuple_index_impl(
std::forward(t),
index,
std::forward(visitor),
detail::size_wrapper::type>::value>()
);
}