I noticed the \"indices trick\" being mentioned in the context of pretty-printing tuples. It sounded interesting, so I followed the link.
Well, that did not go well.
The problem is: we have a std::tuple and we have some function f that we can to call on each element, where f returns an int, and we want to store those results in an array.
Let's start with a concrete case:
template int f(T ) { return sizeof(T); }
std::tuple tup{42, 'x', 3.14};
std::array arr{ f(std::get<0>(tup)),
f(std::get<1>(tup)),
f(std::get<2>(tup)) );
Except writing out all those gets is inconvenient and redundant at best, error-prone at worst.
First we need to include the utility header for std::index_sequence and std::make_index_sequence:
#include
Now, let's say we had a type index_sequence<0, 1, 2>. We could use that to collapse that array initialization into a variadic pack expansion:
template
std::array
call_f_detail(Tuple& tuple, std::index_sequence ) {
return { f(std::get(tuple))... };
}
That's because within the function, f(std::get gets expanded to f(std::get<0>(tuple)), f(std::get<1>(tuple)), f(std::get<2>(tuple)). Which is exactly what we want.
The last detail of the problem is just generating that particular index sequence. C++14 actually gives us such a utility named make_index_sequence
template
std::array::value>
call_f(Tuple& tuple) {
return call_f_detail(tuple,
// make the sequence type sequence<0, 1, 2, ..., N-1>
std::make_index_sequence::value>{}
);
}
whereas the article you linked simply explains how one might implement such a metafunction.
Bare is probably something like, from Luc Danton's answer:
template
using Bare = typename std::remove_cv::type>::type;