Ich habe eine Antwort, die auf Iteration über ein Tupel :
#include <tuple>
#include <utility>
#include <iostream>
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
print(std::tuple<Tp...>& t)
{ }
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
print(std::tuple<Tp...>& t)
{
std::cout << std::get<I>(t) << std::endl;
print<I + 1, Tp...>(t);
}
int
main()
{
typedef std::tuple<int, float, double> T;
T t = std::make_tuple(2, 3.14159F, 2345.678);
print(t);
}
Die übliche Idee ist, die Rekursion zur Kompilierzeit zu verwenden. In der Tat wird diese Idee verwendet, um ein printf zu erstellen, das typsicher ist, wie in den ursprünglichen Tupel-Papieren erwähnt.
Dies kann leicht verallgemeinert werden in eine for_each
für Tupel:
#include <tuple>
#include <utility>
template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
for_each(std::tuple<Tp...> &, FuncT) // Unused arguments are given no names.
{ }
template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
for_each(std::tuple<Tp...>& t, FuncT f)
{
f(std::get<I>(t));
for_each<I + 1, FuncT, Tp...>(t, f);
}
Allerdings erfordert dies dann einige Anstrengungen, um FuncT
etwas mit den entsprechenden Überladungen für jeden Typ darstellen, den das Tupel enthalten könnte. Dies funktioniert am besten, wenn Sie wissen, dass alle Tupel-Elemente eine gemeinsame Basisklasse oder etwas Ähnliches verwenden.