C++类型列表创建子列表
C++ typelist make sublist
假设我有一个类型
template<typename ...Ts>
struct typelist {};
我需要从此列表中获取一个子列表:
template<int startInclusive, int stopExclusive, typename ...Ts>
struct sublist {
using type = ?; //
};
例如
sublist<1, 3, int, float, double, char>::type == typelist<float, double>
当start = 0
我有一个有效的尾实现时:
template<typename ...Ts>
struct typelist {};
template<int N, typename T, typename ...Ts>
struct tail {
using type = typename tail<N - 1, Ts...>::type;
};
template<typename T, typename ...Ts>
struct tail<0, T, Ts...> {
using type = typelist<T, Ts...>;
};
using T = tail<1, int, double>::type;
#include <typeinfo>
#include <cstdio>
int main() {
::printf("%sn", typeid(T).name());
}
但是,我无法为start > 0
工作
像往常一样,std::index_sequence
在这里有所帮助:
template <std::size_t Offset, typename Seq, typename Tuple> struct sublist_impl;
template <std::size_t Offset, std::size_t ... Is, typename Tuple>
struct sublist_impl<Offset, std::index_sequence<Is...>, Tuple>
{
using type = std::tuple<std::tuple_element_t<Offset + Is, Tuple>...>;
};
template<std::size_t startInclusive, std::size_t stopExclusive, typename ...Ts>
using sublist = typename sublist_impl<startInclusive,
std::make_index_sequence<stopExclusive - startInclusive>,
std::tuple<Ts...>>::type;
演示
这可能是矫枉过正,但它有效:
template<typename... Ts>
struct typelist {};
template<class Typelist, typename T>
struct prepend;
template<typename... Ts, typename T>
struct prepend<typelist<Ts...>, T> {
using type = typelist<T, Ts...>;
};
template<int start, int stop, int i, typename... Ts>
struct sublist_impl {
using type = typelist<>;
};
template<int start, int stop, int i, typename T, typename... Ts>
struct sublist_impl<start, stop, i, T, Ts...>
{
private:
static constexpr auto get_sublist_type() {
if constexpr (i < start)
return typename sublist_impl<start, stop, i + 1, Ts...>::type{};
else if constexpr (i < stop)
return typename prepend<typename sublist_impl<
start, stop, i + 1, Ts...>::type, T>::type{};
else
return typelist<>{};
}
public:
using type = decltype(get_sublist_type());
};
template<int start, int stop, typename... Ts>
struct sublist {
using type = typename sublist_impl<start, stop, 0, Ts...>::type;
};
template<int start, int stop, typename... Ts>
using sublist_t = typename sublist<start, stop, Ts...>::type;
static_assert(std::is_same_v<
sublist_t<1, 3, int, float, double, char>, typelist<float, double>>);
static_assert(std::is_same_v<
sublist_t<0, 0, int, float, double, char>, typelist<>>);
static_assert(std::is_same_v<
sublist_t<4, 4, int, float, double, char>, typelist<>>);
static_assert(std::is_same_v<
sublist_t<0, 3, int, float, double, char>, typelist<int, float, double>>);
static_assert(std::is_same_v<
sublist_t<0, 4, int, float, double, char>, typelist<int, float, double, char>>);
只是为了好玩,std::tuple_cat()
的方式
#include <tuple>
#include <type_traits>
template<typename ...Ts>
struct typelist
{ };
template <std::size_t sI, std::size_t sE, std::size_t I, typename T>
constexpr std::enable_if_t<(I >= sI) && (I < sE),
std::tuple<typelist<T>>> getTpl ();
template <std::size_t sI, std::size_t sE, std::size_t I, typename T>
constexpr std::enable_if_t<(I < sI) || (I >= sE),
std::tuple<>> getTpl ();
template <typename ... Ts>
constexpr typelist<Ts...> getList (std::tuple<typelist<Ts>...>);
template <std::size_t sI, std::size_t sE, typename ... Ts,
std::size_t ... Is>
constexpr auto getTplList (typelist<Ts...>, std::index_sequence<Is...>)
-> decltype( getList(std::tuple_cat(getTpl<sI, sE, Is, Ts>()...)) );
template <std::size_t startI, std::size_t stopE, typename ... Ts>
struct sublist
{
using type = decltype(getTplList<startI, stopE>
(typelist<Ts...>{},
std::index_sequence_for<Ts...>{}));
};
int main ()
{
using type1 = typename sublist<1u, 3u, int, float, double, char>::type;
using type2 = typelist<float, double>;
static_assert( std::is_same<type1, type2>::value, "!" );
}
相关文章:
- 动态分配列表 - 创建一个函数,用于删除所有包含偶数值的元素
- 在c++中为链接列表创建复制构造函数/函数
- C++类型列表创建子列表
- 使用初始值设定项列表创建单个项向量
- 如何在C 类中使用备用参数列表创建和使用finturePointer
- C++:从两个包含子类 (typedef) 的列表创建一个列表
- 在线性时间内使用邻接列表创建对顶点
- 从类型列表创建向量元组
- C 链接列表创建链接列表的链接列表
- 需要一个宏来从 std::ostringstream 和 << arg 列表创建 std::string
- 从 2D C 列表创建 boost.geometry.model.polygon
- 如何在C++中使用 STL 列表创建循环
- 使用Templates从参数列表创建std::vector
- 链接列表创建节点
- 如何从 CGAL 中的坐标和拓扑列表创建Polyhedron_3数据结构
- 是否可以使用初始值设定项列表创建临时结构/类
- 如何通过子类型列表创建指针向量
- 为双链接列表创建类的新实例
- 如何用集合顶点列表创建boost子图
- 是否可以为通用元素列表创建排序