Was du falsch gemacht hast war hier:
using type = typename tuple_reverse<
std::tuple<
typename tuple_reverse<std::tuple<Ts..., T>>::type
>
>::type;
es von innen nach außen sucht, neu ordnen Sie die Tupelelemente: tuple<Ts..., T>
, dann, dass Sie versuchen, rückgängig zu machen, dann setzen Sie das Ergebnis in einer tuple
, dann versuchst du das umzukehren das ... huh ?! :)
Dies bedeutet jedes Mal, wenn Sie instanziieren tuple_reverse
geben Sie ein Tupel der gleichen Größe, so dass es nie endet, und rekursiv instanziiert sich für immer. (Wenn diese Rekursion dann beendet ist, fügen Sie den resultierenden Tupel-Typ in ein Tupel ein, so dass Sie ein Ein-Element-Tupel mit einem N-Element-Tupel haben, und umgekehrt, was nichts bewirkt, weil das Umkehren eines Ein-Element-Tupels ein ist no-op)
Sie wollen eines der Elemente abzulösen, dann den Rest umkehren, und verketten es wieder zurück.
using head = std::tuple<T>;
using tail = typename tuple_reverse<std::tuple<Ts...>>::type;
using type = decltype(std::tuple_cat(std::declval<tail>(), std::declval<head>()));
und Sie brauchen nicht in einem Tupel zu wickeln und wieder umkehren :)
Und Sie sollten auch mit dem leeren Tupel Fall umgehen, so ist die ganze Sache:
template <typename... Ts>
struct tuple_reverse;
template <>
struct tuple_reverse<std::tuple<>>
{
using type = std::tuple<>;
};
template <typename T, typename... Ts>
struct tuple_reverse<std::tuple<T, Ts...>>
{
using head = std::tuple<T>;
using tail = typename tuple_reverse<std::tuple<Ts...>>::type;
using type = decltype(std::tuple_cat(std::declval<tail>(), std::declval<head>()));
};
Ich würde es aber anders machen.
nur die Art zu erhalten, C++ 14
template<typename T, size_t... I>
struct tuple_reverse_impl<T, std::index_sequence<I...>>
{
typedef std::tuple<typename std::tuple_element<sizeof...(I) - 1 - I, T>::type...> type;
};
// partial specialization for handling empty tuples:
template<typename T>
struct tuple_reverse_impl<T, std::index_sequence<>>
{
typedef T type;
};
template<typename T>
struct tuple_reverse<T>
: tuple_reverse_impl<T, std::make_index_sequence<std::tuple_size<T>::value>>
{ };
, oder Sie können eine Funktion schreiben, ein aktuelles Tupel Objekt rückgängig zu machen, dann decltype(reverse(t))
die Art zu erhalten verwenden.Zum Umkehren eines Tupels-ähnliches Objekt in C++ 14:
template<typename T, size_t... I>
auto
reverse_impl(T&& t, std::index_sequence<I...>)
{
return std::make_tuple(std::get<sizeof...(I) - 1 - I>(std::forward<T>(t))...);
}
template<typename T>
auto
reverse(T&& t)
{
return reverse_impl(std::forward<T>(t),
std::make_index_sequence<std::tuple_size<T>::value>());
}
In C++ 11 Verwendung <integer_seq.h>
und Rückgabetypen hinzufügen und remove_reference
auf Referenzen aus dem Tupel Typ Streifen (weil tuple_size
und tuple_element
nicht funktionieren mit Verweisen auf Tupel):
template<typename T, typename TT = typename std::remove_reference<T>::type, size_t... I>
auto
reverse_impl(T&& t, redi::index_sequence<I...>)
-> std::tuple<typename std::tuple_element<sizeof...(I) - 1 - I, TT>::type...>
{
return std::make_tuple(std::get<sizeof...(I) - 1 - I>(std::forward<T>(t))...);
}
template<typename T, typename TT = typename std::remove_reference<T>::type>
auto
reverse(T&& t)
-> decltype(reverse_impl(std::forward<T>(t),
redi::make_index_sequence<std::tuple_size<TT>::value>()))
{
return reverse_impl(std::forward<T>(t),
redi::make_index_sequence<std::tuple_size<TT>::value>());
}
Ich glaube nicht, Sie Rekursion müssen dies tun, [tuple_cat] (http://www.cplusplus.com/reference/tuple/tuple_cat/), aber warum wollen Sie ein Tupel umkehren – aaronman