在C ++中创建类型的类型列表组合 [英] Create a type list combination of types in C++

查看:142
本文介绍了在C ++中创建类型的类型列表组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一些工具来根据其他类型的组合创建类型列表。

Im trying to create some tool to create a list of types based on combinations of other types.

假设我们有三种类型

struct A{};
struct B{};
struct C{};

我想获取一个元组列表,其中包含N,A,B或C个类型的每种可能组合。

I want to get a list of tuples which has every possible combination of N types A,B or C.

对于N = 2的情况,这将是

For a N=2 case, this would be

std::tuple<A,A>
std::tuple<A,B>
std::tuple<A,C>
std::tuple<B,A>
std::tuple<B,B>
std::tuple<B,C>
std::tuple<C,A>
std::tuple<C,B>
std::tuple<C,C>

这个想法是创建一个元组来容纳所有这些类型的容器,以便以后存储

The idea is to create a tuple which holds a container for all those types, so I can later store any of those types inside the container list.

template <typename ...Combinations>
using CombinationList = std::tuple<std::vector<Combinations>...>;

我已经有一种机制可以将特定的元素插入适合的容器中,但是我有没有关于如何创建组合的线索。

I already have a mechanism to inserting a particupar element inside the container in which it fits, but I have no clue on how to create the combinatios.

在评论中,人们建议使用 std :: vector< Combination< std :: variant< A,C,B> ;, std ::变体< A,B,C>> 。尽管这从技术上解决了问题,但我不愿使用它,因为A,B C的大小非常不同,我不想在运行时访问变体。此外,在某些时候,我需要将

On the comments people has suggestes using std::vector<Combination<std::variant<A,C,B>, std::variant<A,B,C>>>. Althought this technically solve the problem, I prefer not to use it, as A, B C and has very different sizes and I dont want to visit the variants at runtime. Also, at some point I will need to upload the all the data in the containers in

std::tuple<std::vector<Combination>...>

到GPU,所以我不能在这里使用std :: variant。

to the GPU, so I cant use std::variant here.

我该怎么办?

谢谢!

PD:这与此问题有关枚举的组合爆炸值(729个组合...)
在这个问题中,我问我如何轻松生成将放入容器内的类型。现在,我需要生成容器。

PD: This is related to this question Combination explosion of an enum value (729 combinations...) In that question I asked how I could generate easily the types that would go inside the container. Now I need to generate the containers .

推荐答案


我已经有了插入特殊元素的机制在适合它的容器中,但是我不知道如何创建组合。

I already have a mechanism to inserting a particupar element inside the container in which it fits, but I have no clue on how to create the combinatios.

假设您有一个类型列表(例如 A,B,C )和无符号整数 N ,我建议使用使用

Suppose you have a list of types (say A, B, C) and an unsigned integer N, I propose a using

template <std::size_t N, typename ... Ts>
using Combinations = ???

定义为 std :: tuple 包含所有组合的 std :: tuple s的列表。

that is defined as a std::tuple containing a list of std::tuples with all combinations.

例如,

Combinations<2u, A, B, C>

成为

  std::tuple<
      std::tuple<A,A>, std::tuple<A,B>, std::tuple<A,C>,
      std::tuple<B,A>, std::tuple<B,B>, std::tuple<B,C>,
      std::tuple<C,A>, std::tuple<C,B>, std::tuple<C,C>>

以下是完整的C ++ 11示例

The following is a full compiling C++11 example

#include <tuple>
#include <vector>
#include <type_traits>

struct A {};
struct B {};
struct C {};

template <typename T, typename ... Ts>
constexpr std::tuple<T, Ts...> addTupleType (std::tuple<Ts...>);

template <typename T, typename ... Ts>
constexpr auto addType ()
   -> std::tuple<decltype(addTupleType<T>(std::declval<Ts>()))...>;

template <typename ... Ts, typename ... Us>
constexpr auto getCombinations (std::integral_constant<std::size_t, 0u>,
                                std::tuple<Ts...> t, std::tuple<Us ...> u)
   -> decltype( u );

template <std::size_t N, typename ... Ts, typename ... Us,
          typename std::enable_if<(N > 0u), bool>::type = true>
constexpr auto getCombinations (std::integral_constant<std::size_t, N>,
                                std::tuple<Ts...> t, std::tuple<Us ...>)
   -> decltype (getCombinations(
         std::integral_constant<std::size_t, N-1u>{}, t,
         std::tuple_cat(addType<Ts, Us...>()...)));

template <std::size_t N, typename ... Ts>
using Combinations
   = decltype(getCombinations(
         std::integral_constant<std::size_t, N-1u>{},
         std::declval<std::tuple<Ts...>>(),
         std::declval<std::tuple<std::tuple<Ts>...>>()));

template <typename ... Ts>
constexpr auto CombListHelper (std::tuple<Ts...>)
   -> std::tuple<std::vector<Ts>...>;

template <typename T>
using CombinationList = decltype(CombListHelper(std::declval<T>()));


int main()
 {
   using type_1 = Combinations<2u, A, B, C>;
   using type_2 = std::tuple<
      std::tuple<A,A>, std::tuple<A,B>, std::tuple<A,C>,
      std::tuple<B,A>, std::tuple<B,B>, std::tuple<B,C>,
      std::tuple<C,A>, std::tuple<C,B>, std::tuple<C,C>>;

   static_assert( std::is_same<type_1, type_2>::value, "!" );

   using type_3 = CombinationList<Combinations<2u, A, B, C>>;
   using type_4 = std::tuple<
      std::vector<std::tuple<A,A>>, std::vector<std::tuple<A,B>>,
      std::vector<std::tuple<A,C>>, std::vector<std::tuple<B,A>>,
      std::vector<std::tuple<B,B>>, std::vector<std::tuple<B,C>>,
      std::vector<std::tuple<C,A>>, std::vector<std::tuple<C,B>>,
      std::vector<std::tuple<C,C>>>;

   static_assert( std::is_same<type_3, type_4>::value, "!" );
 }

这篇关于在C ++中创建类型的类型列表组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆