问题描述
如何反转元组中的类型?例如,我希望 reverse_tuple< std :: tuple< int,char,bool> :: type 是 std :: tuple< bool ,char,int> 。我尝试了以下操作,但没有成功。我做错了什么?
How do I reverse the types in a tuple? For example, I want reverse_tuple<std::tuple<int, char, bool>>::type to be std::tuple<bool, char, int>. I tried doing the following but it didn't work. What did I do wrong?
#include <type_traits> #include <tuple> template <typename... Ts> struct tuple_reverse; template <typename T, typename... Ts> struct tuple_reverse<std::tuple<T, Ts...>> { using type = typename tuple_reverse< std::tuple< typename tuple_reverse<std::tuple<Ts..., T>>::type > >::type; }; template <typename T> struct tuple_reverse<std::tuple<T>> { using type = std::tuple<T>; }; int main() { using result_type = std::tuple<int, bool, char>; static_assert( std::is_same< tuple_reverse<var>::type, std::tuple<char, bool, int> >::value, "" ); }
这是我的错误:
推荐答案
您在这里做错了:
using type = typename tuple_reverse< std::tuple< typename tuple_reverse<std::tuple<Ts..., T>>::type > >::type;
从内而外看,您对元组元素进行了重新排序: tuple< ; Ts ...,T> ,然后尝试将其反转,然后将结果放入 tuple ,然后尝试将其反转那个 ...是吗? :)
Looking at it from the inside out, you reorder the tuple elements: tuple<Ts..., T>, then you try to reverse that, then you put the result in a tuple, then you try to reverse that ... huh?! :)
这意味着每次实例化 tuple_reverse 时,都给它一个相同大小的元组,因此永远不会完成,并永久地递归实例化自身。 (然后,如果该递归甚至完成了,则将结果元组类型放入一个元组中,这样您就有一个包含N元元素元组的单元元素元组,并对其进行反转,这无济于事,因为反转单元元组是一个
This means each time you instantiate tuple_reverse you give it a tuple of the same size, so it never finishes, and recursively instantiates itself forever. (Then, if that recursion even finished, you put the resulting tuple type into a tuple, so you have a single-element tuple containing an N-element tuple, and reverse that, which does nothing because reversing a single-element tuple is a no-op.)
您要剥离其中一个元素,然后反转其余元素,然后再次将其连接起来:
You want to peel off one of the elements, then reverse the rest, and concatenate it back again:
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>()));
您不需要将其包装在元组中并再次反转:)
And you don't need to wrap it in a tuple and reverse it again :)
您还应该处理空的元组大小写,所以整个事情是:
And you should also handle the empty tuple case, so the whole thing is:
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>())); };
我会做不同的事情。
使用C ++ 14来获取类型
To get just the type, using 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>> { };
或者您可以编写一个函数来反转实际的元组对象,然后使用 decltype(reverse(t))获取类型。要在C ++ 14中反转类似元组的对象:
Or you can write a function to reverse an actual tuple object, then use decltype(reverse(t)) to get the type. To reverse a tuple-like object 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>()); }
在C ++ 11中使用并添加返回类型和使用 remove_reference 删除元组类型的引用(因为 tuple_size 和 tuple_element 不适用于元组引用):
In C++11 use <integer_seq.h> and add return types and use remove_reference to strip references from the tuple type (because tuple_size and tuple_element don't work with references to tuples):
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>()); }
这篇关于如何反转元组类型中元素类型的顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!