创建从std :: tuple开始的子元组< some_types ...> [英] Creating a sub-tuple starting from a std::tuple<some_types...>
问题描述
让我们假设给出了 std :: tuple< some_types ...>
。我想创建一个新的 std :: tuple
其类型是索引在 [0,sizeof ...(some_types) - 2]
。例如,让我们假设开始元组是 std :: tuple< int,double,bool>
。我想获得一个定义为 std :: tuple< int,double>
的子元组。
我对可变模板很新。作为第一步,我试图写一个 struct
负责存储不同类型的原始 std :: tuple
目的是创建一个相同类型的新元组(如 std :: tuple< decltype(old_tuple)> new_tuple
)。
模板< typename ... types>
struct type_list;
template< typename T,typename ... types>
struct type_list< T,types ...> :public type_list< types ...> {
typedef T type;
};
template< typename T>
struct type_list< T> {
typedef T type;
};
我想做的是:
std :: tuple< type_list< bool,double,int> :: type ...> new_tuple //这将不工作
下一步将是丢弃参数包。如何访问存储在 type_list
中的多个类型
?
感谢。
这是一种直接解决问题的方法。
模板< unsigned ... s> struct seq {typedef seq< s ...>类型; };
template< unsigned max,unsigned ... s> struct make_seq:make_seq {};
template< unsigned ... s> struct make_seq< 0,s ...>:seq< s ...> {};
template< unsigned ... s,typename Tuple>
auto extract_tuple(seq< s ...>,Tuple& tup){
return std :: make_tuple(std :: get< s>(tup)...);
}
您可以使用如下:
std :: tuple< int,double,bool> my_tup;
auto short_tup = extract_tuple(make_seq< 2>(),my_tup);
auto skip_2nd = extract_tuple(seq< 0,2>(),my_tup);
并使用 decltype
类型。
另一种方法是写 append_type
,它接受一个类型和一个 tuple< ...>
,并将该类型添加到结尾。然后添加到 type_list
:
模板< template< typename ... > class target>
struct gather {
typedef typename type_list< types ...> :: template gather< target> :: type parent_result;
typedef typename append< parent_result,T> :: type type;
};
这样就可以累积 type_list
插入包含模板
的任意参数包。但这不是您的问题所必需的。
Let us suppose that a std::tuple<some_types...>
is given. I would like to create a new std::tuple
whose types are the ones indexed in [0, sizeof...(some_types) - 2]
. For instance, let's suppose that the starting tuple is std::tuple<int, double, bool>
. I would like to obtain a sub-tuple defined as std::tuple<int, double>
.
I'm quite new to variadic templates. As a first step I tried to write a struct
in charge of storing the different types of the original std::tuple
with the aim of creating a new tuple of the same kind (as in std::tuple<decltype(old_tuple)> new_tuple
).
template<typename... types>
struct type_list;
template<typename T, typename... types>
struct type_list<T, types...> : public type_list<types...> {
typedef T type;
};
template<typename T>
struct type_list<T> {
typedef T type;
};
What I would like to do is something like:
std::tuple<type_list<bool, double, int>::type...> new_tuple // this won't work
And the next step would be of discarding the last element in the parameter pack. How can I access the several type
's stored in type_list
? and how to discard some of them?
Thanks.
Here is a way to solve your problem directly.
template<unsigned...s> struct seq { typedef seq<s...> type; };
template<unsigned max, unsigned... s> struct make_seq:make_seq<max-1, max-1, s...> {};
template<unsigned...s> struct make_seq<0, s...>:seq<s...> {};
template<unsigned... s, typename Tuple>
auto extract_tuple( seq<s...>, Tuple& tup ) {
return std::make_tuple( std::get<s>(tup)... );
}
You can use this as follows:
std::tuple< int, double, bool > my_tup;
auto short_tup = extract_tuple( make_seq<2>(), my_tup );
auto skip_2nd = extract_tuple( seq<0,2>(), my_tup );
and use decltype
if you need the resulting type.
A completely other approach would be to write append_type
, which takes a type and a tuple<...>
, and adds that type to the end. Then add to type_list
:
template<template<typename...>class target>
struct gather {
typedef typename type_list<types...>::template gather<target>::type parent_result;
typedef typename append< parent_result, T >::type type;
};
which gives you a way to accumulate the types of your type_list
into an arbitrary parameter pack holding template
. But that isn't required for your problem.
这篇关于创建从std :: tuple开始的子元组< some_types ...>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!