获取包中的所有子包

2024-04-17

PowerSet<Pack<Types...>>::type是给出一个由所有子集组成的包组成的包Types...(现在假设静态断言中的每个类型Types...是不同的)。例如,

PowerSet<Pack<int, char, double>>::type

is to be

Pack<Pack<>, Pack<int>, Pack<char>, Pack<double>, Pack<int, char>, Pack<int, double>, Pack<char, double>, Pack<int, char, double>>

现在,我已经解决了这个练习并对其进行了测试,但是我的解决方案很长,希望听到一些更优雅的想法。我并不是要求任何人审查我的解决方案,而是建议一种新的方法,也许用一些伪代码勾勒出他们的想法。

如果你想知道,这就是我所做的:首先,我回忆起高中时的情况,一组 N 个元素有 2^N 个子集。每个子集对应于 N 位二进制数,例如001010...01(N 位长),其中 0 表示该元素在子集中,1 表示该元素在子集中 该元素不在子集中。因此 000...0 代表空子集,111...1 代表整个集合本身。 因此,使用(模板)序列 0,1,2,3,...2^N-1,我形成了 2^N 个索引序列,每个索引序列对应于 该序列中的整数,例如index_sequence 将对应于该序列中的 13。然后这 2^N 个索引序列中的每一个 将被转换为所需的 2^N 子集Pack<Types...>.

我下面的解决方案很长,而且我知道有一种比上面描述的非常机械的方法更优雅的方法。 如果您想到了更好的计划(可能也更短,因为它更具递归性或其他什么),请发布您的想法,以便我可以接受 你更好的计划,希望写出一个更短的解决方案。如果您认为可能需要花费时间,我不希望您完整地写出您的解决方案 一段时间(除非你愿意)。但目前,除了我所做的之外,我想不出其他方法。这是我目前的较长解决方案,以防您想阅读它:

#include <iostream>
#include <cmath>
#include <typeinfo>

// SubsetFromBinaryDigits<P<Types...>, Is...>::type gives the sub-pack of P<Types...> where 1 takes the type and 0 does not take the type.  The size of the two packs must be the same.
// For example, SubsetFromBinaryDigits<Pack<int, double, char>, 1,0,1>::type gives Pack<int, char>.

template <typename, typename, int...> struct SubsetFromBinaryDigitsHelper;

template <template <typename...> class P, typename... Accumulated, int... Is>
struct SubsetFromBinaryDigitsHelper<P<>, P<Accumulated...>, Is...> {
    using type = P<Accumulated...>;
};

template <template <typename...> class P, typename First, typename... Rest, typename... Accumulated, int FirstInt, int... RestInt>
struct SubsetFromBinaryDigitsHelper<P<First, Rest...>, P<Accumulated...>, FirstInt, RestInt...> :
    std::conditional<FirstInt == 0,
        SubsetFromBinaryDigitsHelper<P<Rest...>, P<Accumulated...>, RestInt...>,
        SubsetFromBinaryDigitsHelper<P<Rest...>, P<Accumulated..., First>, RestInt...>
    >::type {};

template <typename, int...> struct SubsetFromBinaryDigits;

template <template <typename...> class P, typename... Types, int... Is>
struct SubsetFromBinaryDigits<P<Types...>, Is...> : SubsetFromBinaryDigitsHelper<P<Types...>, P<>, Is...> {};

// struct NSubsets<P<Types...>, IntPacks...>::type is a pack of packs, with each inner pack being the subset formed by the IntPacks.
// For example, NSubsets< Pack<int, char, long, Object, float, double, Blob, short>, index_sequence<0,1,1,0,1,0,1,1>, index_sequence<0,1,1,0,1,0,1,0>, index_sequence<1,1,1,0,1,0,1,0> >::type will give
// Pack< Pack<char, long, float, Blob, short>, Pack<char, long, float, Blob>, Pack<int, char, long, float, Blob> >

template <typename, typename, typename...> struct NSubsetsHelper;

template <template <typename...> class P, typename... Types, typename... Accumulated>
struct NSubsetsHelper<P<Types...>, P<Accumulated...>> {
    using type = P<Accumulated...>;
};

template <template <typename...> class P, typename... Types, typename... Accumulated, template <int...> class Z, int... Is, typename... Rest>
struct NSubsetsHelper<P<Types...>, P<Accumulated...>, Z<Is...>, Rest...> :
    NSubsetsHelper<P<Types...>, P<Accumulated..., typename SubsetFromBinaryDigits<P<Types...>, Is...>::type>, Rest...> {};

template <typename, typename...> struct NSubsets;

template <template <typename...> class P, typename... Types, typename... IntPacks>
struct NSubsets<P<Types...>, IntPacks...> : NSubsetsHelper<P<Types...>, P<>, IntPacks...> {};

// Now, given a pack with N types, we transform index_sequence<0,1,2,...,2^N> to a pack of 2^N index_sequence packs, with the 0's and 1's of each
// index_sequence pack forming the binary representation of the integer.  For example, if N = 2, then we have
// Pack<index_sequence<0,0>, index_sequence<0,1>, index_sequence<1,0>, index_sequence<1,1>>.  From these, we can get the
// power set, i.e. the set of all subsets of the original pack.

template <int N, int Exponent, int PowerOfTwo>
struct LargestPowerOfTwoUpToHelper {
    using type = typename std::conditional<(PowerOfTwo > N),
        std::integral_constant<int, Exponent>,
        LargestPowerOfTwoUpToHelper<N, Exponent + 1, 2 * PowerOfTwo>
    >::type;
    static const int value = type::value;
};

template <int N>
struct LargestPowerOfTwoUpTo : std::integral_constant<int, LargestPowerOfTwoUpToHelper<N, -1, 1>::value> {};

constexpr int power (int base, int exponent) {
    return std::pow (base, exponent);
}

template <int...> struct index_sequence {};

// For example, PreBinaryIndexSequence<13>::type is to be index_sequence<0,2,3>, since 13 = 2^3 + 2^2 + 2^0.
template <int N, int... Accumulated>
struct PreBinaryIndexSequence {  // Could use another helper, since LargestPowerOfTwoUpToHelper<N, -1, 1>::value is being used twice.
    using type = typename PreBinaryIndexSequence<N - power(2, LargestPowerOfTwoUpToHelper<N, -1, 1>::value), LargestPowerOfTwoUpToHelper<N, -1, 1>::value, Accumulated...>::type;
};

template <int... Accumulated>
struct PreBinaryIndexSequence<0, Accumulated...> {
    using type = index_sequence<Accumulated...>;
};

// For example, BinaryIndexSequenceHelper<index_sequence<>, index_sequence<0,2,3>, 0, 7>::type is to be index_sequence<1,0,1,1,0,0,0,0> (the first index with position 0, and the last index is position 7).
template <typename, typename, int, int> struct BinaryIndexSequenceHelper;

template <template <int...> class Z, int... Accumulated, int First, int... Rest, int Count, int MaxCount>
struct BinaryIndexSequenceHelper<Z<Accumulated...>, Z<First, Rest...>, Count, MaxCount> : std::conditional<First == Count,
        BinaryIndexSequenceHelper<Z<Accumulated..., 1>, Z<Rest...>, Count + 1, MaxCount>,
        BinaryIndexSequenceHelper<Z<Accumulated..., 0>, Z<First, Rest...>, Count + 1, MaxCount>
    >::type {};

// When the input pack is emptied, but Count is still less than MaxCount, fill the rest of the acccumator pack with 0's.
template <template <int...> class Z, int... Accumulated, int Count, int MaxCount>
struct BinaryIndexSequenceHelper<Z<Accumulated...>, Z<>, Count, MaxCount> : BinaryIndexSequenceHelper<Z<Accumulated..., 0>, Z<>, Count + 1, MaxCount> {};

template <template <int...> class Z, int... Accumulated, int MaxCount>
struct BinaryIndexSequenceHelper<Z<Accumulated...>, Z<>, MaxCount, MaxCount> {
    using type = Z<Accumulated...>;
};

// At last, BinaryIndexSequence<N> is the binary representation of N using index_sequence, e.g. BinaryIndexSequence<13,7> is index_sequence<1,0,1,1,0,0,0>.
template <int N, int NumDigits>
using BinaryIndexSequence = typename BinaryIndexSequenceHelper<index_sequence<>, typename PreBinaryIndexSequence<N>::type, 0, NumDigits>::type;

// Now define make_index_sequence<N> to be index_sequence<0,1,2,...,N-1>.
template <int N, int... Is>
struct make_index_sequence_helper : make_index_sequence_helper<N-1, N-1, Is...> {};  // make_index_sequence_helper<N-1, N-1, Is...> is derived from make_index_sequence_helper<N-2, N-2, N-1, Is...>, which is derived from make_index_sequence_helper<N-3, N-3, N-2, N-1, Is...>, which is derived from ... which is derived from make_index_sequence_helper<0, 0, 1, 2, ..., N-2, N-1, Is...>

template <int... Is>
struct make_index_sequence_helper<0, Is...> {
    using type = index_sequence<Is...>;
};

template <int N>
using make_index_sequence = typename make_index_sequence_helper<N>::type;

// Finally, ready to define PowerSet itself.
template <typename, typename> struct PowerSetHelper;

template <template <typename...> class P, typename... Types, template <int...> class Z, int... Is>
struct PowerSetHelper<P<Types...>, Z<Is...>> : NSubsets< P<Types...>, BinaryIndexSequence<Is, sizeof...(Types)>... > {};

template <typename> struct PowerSet;

template <template <typename...> class P, typename... Types>
struct PowerSet<P<Types...>> : PowerSetHelper<P<Types...>, make_index_sequence<power(2, sizeof...(Types))>> {};

// -----------------------------------------------------------------------------------------------------------------------------------------------
// Testing

template <typename...> struct Pack {};

template <typename Last>
struct Pack<Last> {
    static void print() {std::cout << typeid(Last).name() << std::endl;}
};

template <typename First, typename ... Rest>
struct Pack<First, Rest...> {
    static void print() {std::cout << typeid(First).name() << ' ';  Pack<Rest...>::print();}
};

template <int Last>
struct index_sequence<Last> {
    static void print() {std::cout << Last << std::endl;}
};

template <int First, int ... Rest>
struct index_sequence<First, Rest...> {
    static void print() {std::cout << First << ' ';  index_sequence<Rest...>::print();}
};

int main() {
    PowerSet<Pack<int, char, double>>::type powerSet;
    powerSet.print();
}

这是我的尝试:

template<typename,typename> struct Append;

template<typename...Ts,typename T>
struct Append<Pack<Ts...>,T>
{
    using type = Pack<Ts...,T>;
};

template<typename,typename T=Pack<Pack<>>>
struct PowerPack
{
    using type = T;
};

template<typename T,typename...Ts,typename...Us>
struct PowerPack<Pack<T,Ts...>,Pack<Us...>>
    : PowerPack<Pack<Ts...>,Pack<Us...,typename Append<Us,T>::type...>>
{
};

实例 http://coliru.stacked-crooked.com/a/25a68ab0ccce643f

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取包中的所有子包 的相关文章

随机推荐

  • Android 编程错误

    我正在使用 Eclipse Galileo 编写 Android 你好 测试 教程 http developer android com resources tutorials testing helloandroid test html
  • ASP.net 页面在导入语句上出现错误,但我确实有引用吗?

    任何想法为什么我在我的 MVC2 项目中收到以下错误 即使在项目本身中我肯定有对 system Web Entity 的引用 Compiler Error Message CS0234 The type or namespace name
  • 后台根据时间激活本地通知

    因此 我有一个包含重复间隔本地通知的应用程序 我想添加一个在睡眠期间暂停通知的功能 到目前为止 我已经为用户创建了两个日期选择器 以指定他们想要停止重复间隔的时间以及自动重新启动的时间 我还为他们添加了一个 uiswitch 来激活睡眠模式
  • 在 PHP 中将 Oauth 2.0 访问令牌传递给 Fusion Tables API 时出现无效凭据错误

    我已经达到了沮丧的地步 正在寻求帮助 我整个周末都在学习新东西 以便尝试弄清楚如何使用需要通过 Oauth 2 0 进行身份验证的 goolge fusion table API 我开始使用 php 进行开发只是因为我能够找到一些帮助我走上
  • 将事件处理程序应用于动态控制

    我有一个用户窗体 可以动态放置commandButton到用户表单上 但我似乎无法正确设置动态事件处理程序 下面显示了我如何设置动态按钮的代码 Set cButton Me Controls Add Forms CommandButton
  • 使 fetch 调用真正同步

    是的 我想完全同步 我知道它会完全停止我唯一的线程 但我真的需要它 因为我使用一些我不想更改的 SDK 并且在这个 SDK 中 您需要传递一个将被调用且会更改的函数那里有一些价值 比如 function onNonce stuff cons
  • 如何使用 Sql Server 2008 删除表中的前 1000 行?

    我在 SQL Server 中有一个表 我想从中删除前 1000 行 但是 我尝试了此操作 但我不是只删除前 1000 行 而是删除了表中的所有行 这是代码 delete from mytab select top 1000 a1 a2 a
  • 如何在AWS EC2服务器中编写cron作业

    我在 AWS EC2 中创建了一个 cron 作业 但它不起作用 我按照以下步骤创建 crontab 第1步 我登录到AWS EC2实例 step 2 crontab e 第三步 插入模式 第4步 我输入了 php var www html
  • 处理多种表单和打印内容[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 您好 我对
  • 从 JBPM WorkItemHandler 抛出异常?

    我对从 JBPM 工作项处理程序抛出异常以及在业务流程中的其他地方处理异常的主题有点困惑 我们使用 JBPM 6 0 3 在 Jboss EAP 6 1 中运行 The JBPM 用户指南 http docs jboss org jbpm
  • ExtJS TreeGrid 中的复选框列

    有没有办法在新的 extjs 小部件 TreeGrid 中包含复选框列 将节点属性标记为 false true 并不像 TreePanel 那样有效 Cheers 我修改了 Ext ux tree TreeGridNodeUI 类来实现此功
  • 正则表达式捕获 VBA 注释

    我正在尝试捕获 VBA 注释 到目前为止我有以下内容 Z 它捕获以单引号开头但在字符串末尾之前不包含任何双引号的任何内容 即它不会匹配双引号字符串中的单引号 dim s as string a string variable works s
  • 未知层:当我尝试加载模型时 KerasLayer

    当我尝试将模型另存为 hdf5 时 path path h5 model save path 然后再次加载模型 my reloaded model tf keras models load model path 我收到以下错误 ValueE
  • 运行为黑莓设备创建的黑莓应用程序需要哪些步骤?

    我使用 java me 和 BlackBerry 特定 API 创建了一个 BlackBerry 应用程序 它在黑莓模拟器上运行良好 我想知道如何将此应用程序部署到 BlackBerry 设备 从文档中我发现 在设备上运行 BlackBer
  • XSLTProcessor::importStylesheet() 中的多个 PHP 警告

    Errors Warning XSLTProcessor importStylesheet xsltprocessor importstylesheet Undefined variable in transform php on line
  • 在 Cloud Dataflow 中进行 ETL 和解析 CSV 文件

    我是云数据流和 Java 的新手 所以我希望这是正确的问题 我有一个 csv 文件 其中有 n 个列和行 可以是字符串 整数或时间戳 我需要为每一列创建一个新的 PCollection 吗 我在示例中找到的大多数文档都类似于 PCollec
  • 如何在 Rails 6 或 Rails 7 alpha 引擎中使用 jqueryUI

    如果有人能够展示在 Rails 6 或 Rails 7 Alpha 2 引擎中使用 jquery ui 所需的确切步骤 我将不胜感激 我无法让 importmap rails 在 Rails 7 引擎中工作 也无法让 webpacker 在
  • 非静态字段、方法或属性需要对象引用

    这是我第一次使用列表 但我似乎做得不太好 我有一个客户类 其中包含客户列表作为客户类中的属性 可以这样做吗 public class Customer private List
  • Pandas:重新采样数据帧列,获取与最大值对应的离散特征

    样本数据 import pandas as pd import numpy as np import datetime data value 1 2 4 3 names joe bob joe bob start end datetime
  • 获取包中的所有子包

    PowerSet