如何使用可变模板来展平类型树?

2023-11-23

我有一个这样的构造:

template<typename... Ts>
struct List {}

typedef List<char,List<int,float,List<int,unsigned char>>,List<unsigned,short>> MyList;

我想基本上将其扁平化为一个列表。什么是最好的方法?我想如果我摆弄它足够长的时间,我可以用递归来做一些事情,但有些事情告诉我应该有更好的方法。

我想要的上述树的结果应该与此类似:

typedef List<char,int,float,int,unsigned char,unsigned,short> FlattenedList;

这是我的第一次尝试:

template<typename... Ts>
struct List{};

template<typename... Ts>
struct FlattenTree{
    typedef List<Ts...> Type;
};
template<typename... Ts, typename... Us, typename... Vs>
struct FlattenTree<Ts...,List<Us...>,Vs...>{
    typedef typename FlattenTree<Ts..., Us..., Vs...>::Type Type;
};

但这会导致此错误:error C3515: if an argument for a class template partial specialization is a pack expansion it shall be the last argument

里奇指出hereMSVC2013 抱怨什么,所以这里没有编译器错误:

§ 14.8.2.5(从类型推导模板参数)第 5 段列出了无法推导模板参数的上下文。相关的是列表中的最后一个:

— A function parameter pack that does not occur at the end of the parameter-declaration-clause.

Update:

我想人们可以在最后放入一个虚拟参数,继续将第一个参数移动到末尾,或者如果它是列表,则将其扩展到前面,并专门将第一个参数作为我的虚拟参数来停止递归。不过,对于编译器来说,仅仅为了压平列表似乎需要做很多工作。

namespace Detail{
    struct MyMagicType {};
    template<typename T, typename... Ts>
    struct FlattenTree{
        typedef typename FlattenTree<Ts..., T>::Type Type;
    };
    template<typename... Ts>
    struct FlattenTree<MyMagicType,Ts...>{      //termination case
        typedef List<Ts...> Type;
    };
    template<typename... Ts, typename... Us>
    struct FlattenTree<List<Ts...>, Us...>{
        typedef typename FlattenTree<Ts..., Us...>::Type Type;
    };              //expand Ts to front because they may hold more nested Lists
}

template<typename... Ts>
struct FlattenTree{
    typedef typename Detail::FlattenTree<Ts...,Detail::MyMagicType>::Type Type;
};

这适用于 MSVC2013,但我认为这不是最好的方法,因为我需要一个虚拟类型,并且它会给编译器带来很大的负载。我想将它与包含 500 多个元素的列表一起使用。


另一种方法是使用辅助类和累加器列表而不是MyMagicType。我们从一个空的开始List<>然后用输入列表中的类型填充它:

#include <type_traits>

template <class... Ts> struct List {};

// first parameter - accumulator
// second parameter - input list
template <class T, class U>
struct flatten_helper;

// first case - the head of the List is List too
// expand this List and continue
template <class... Ts, class... Heads, class... Tail>
struct flatten_helper<List<Ts...>, List<List<Heads...>, Tail...>> {
    using type = typename flatten_helper<List<Ts...>, List<Heads..., Tail...>>::type;
};

// second case - the head of the List is not a List
// append it to our new, flattened list
template <class... Ts, class Head, class... Tail>
struct flatten_helper<List<Ts...>, List<Head, Tail...>> {
    using type = typename flatten_helper<List<Ts..., Head>, List<Tail...>>::type;
};

// base case - input List is empty
// return our flattened list
template <class... Ts>
struct flatten_helper<List<Ts...>, List<>> {
    using type = List<Ts...>;
};

// wrapper around flatten_helper
template <class T> struct flatten;

// start with an empty accumulator
template <class... Ts>
struct flatten<List<Ts...>> {
    using type = typename flatten_helper<List<>, List<Ts...>>::type;
};

auto main() -> int {
    using Types = List<int, List<float, List<double, List<char>>>>;
    using Flat = flatten<Types>::type;

    static_assert(std::is_same<Flat, List<int, float, double, char>>::value, "Not the same");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用可变模板来展平类型树? 的相关文章

随机推荐

  • 处理 Windows 8 网格中的滑动手势

    我正在尝试实现一个自定义控件 其中包含一个网格 其中一些画布元素作为子元素 当在网格上进行滑动操作时 我打算对画布元素执行一些操作 我无法处理网格的滑动 我已在msdn win8 开发论坛 我和你们的情况一样 因为没有关于如何完成此操作的示
  • JavaScript 检查文件大小

    是否可以继续使用 javascript 检查网络服务器上文件的文件大小 例如http www mysite com myfile js 大于 0 字节 如果是 则返回 true 或 false 值 提前致谢 理论上 您可以使用 XHR 发出
  • Jackson 中不区分大小写的 JsonNode

    我需要反序列化 JSON 对象并以不区分大小写的方式访问字段 例子 String s FOO 123 ObjectMapper mapper new ObjectMapper JsonNode node mapper readTree s
  • 编译gdb进行远程调试

    我正在尝试远程调试在arm9上运行的应用程序 到目前为止 我已经能够在我的设备上交叉编译和执行 gdbserver 获取 gdb 7 2 源代码并提取它们 configure target arm none linux gnueabi wi
  • python matplotlib 热图颜色条从透明

    如何实现这样的python matplotlib heatmap colorbar plt imshow a aspect auto cmap plt cm gist rainbow r plt colorbar matplotlib 库中
  • 当奇数宽度的 div 被分割 50%/50% 时,剩余的 1px 会发生什么?

    假设我想为以下内容制作背景div wrapper这样使用两个 div 一半是蓝色 一半是红色width 50 像这样 HTML div div div div div div CSS body html wrapper width 100
  • 使用 Flex/Bison 的解释器 REPL

    我已经为类 C 语言编写了一个解释器 使用 Flex 和 Bison 作为扫描器 解析器 执行完整的程序文件时它工作正常 现在我正在尝试在解释器中实现 REPL 以供交互式使用 我希望它像 Ruby 或 ML 中的命令行解释器一样工作 显示
  • AutoFac:注入 NULL 值

    我想使用 AutoFac 将当前主体注入需要它的对象中 假设我有一个对象 AuthorizationValidator 正在执行安全检查 它看起来像这样 public AuthorizationValidator IAuthorizatio
  • 是否可以通过JNI将静态库链接到Java?

    是否可以构建 HelloWorld lib 并使用 JNI 将其加载到 Java 应用程序 或者它只适用于共享库 我在 JNI 文档中找不到明确的答案 没有提到 静态库 它需要是一个动态库 幸运的是 您可以从静态库构建动态库
  • 安置新问题

    In this 我需要 C 数组类模板 它是固定大小的 基于堆栈的并且不需要默认构造函数我发布了一段代码 即使用带有 char 数组的放置 new 对我来说 这是绝对正常的事情 但根据评论 这段代码是错误的 谁能更详细地解释一下吗 具体来说
  • 有没有一种方法可以更新一个功能文件中的标头并使用 Karate.config.js 中的身份验证令牌?

    我想仅在一个功能文件中更新我的通用标头 Accept 和 Content Type 但是 我想使用已在 Karate config cs 文件中配置的授权令牌 你能帮我解决这个问题吗 文档对此进行了详细解释 https github com
  • 以编程方式确定 Cisco VPN 客户端是否已连接

    我正在使用基本的 Cisco VPN 客户端 我相信是 v 5 无论如何 是否可以以编程方式确定特定配置文件 或与此相关的任何配置文件 是否已连接 我希望以某种方式从客户本身获得状态 我不想尝试 ping VPN 另一端的某个 IP 才能查
  • PHP 中 ord 或 charCodeAt() 的 UTF-8 安全等效项

    我需要能够使用 ord 来获取与 javascript 的 charCodeAt 函数相同的值 问题是 ord 不支持 UTF8 如何在 PHP 中将 转换为 260 我尝试过一些 uniord 函数 但它们都报告 256 而不是 260
  • 有人知道如何在记事本++中使用正则表达式查找阿拉伯字符吗?

    我正在尝试使用 Notepad CTRL F 和正则表达式来检测网页 HTML 中的阿拉伯字符 我输入以下内容作为我的搜索词 它返回所有字符 u0600 u06FF 我正在使用的随机文本示例块 awr4tgagas qa4tq4tw q4t
  • 如何在 JBoss AS 7 中部署 war 文件?

    我下载了 JBoss Application Server 5 并成功部署了一个 war 文件 我将具有简单 index jsp 文件的 Hello war 复制粘贴到 jboss 5 1 0 GA jdk6 jboss 5 1 0 GA
  • React Native Module AppRegistry 不是已注册的可调用模块

    我在处理我们团队正在开发的共享 github 项目时遇到问题 我已经为这个问题苦苦挣扎了大约一周 但没有任何运气 问题是在我团队的计算机上运行的全新克隆无法在我的计算机上正常运行 它抛出错误 Module AppRegistry 不是可调用
  • 滑动手势在全屏模式下的 YouTubePlayerView 中不起作用

    我正在使用YouTube API 我想应用Swipe左右手势开启YouTubePlayerView在全屏模式下 The Swipe手势不起作用Android4 0 版本时YouTubePlayerView处于全屏模式 请在这件事上给予我帮助
  • 处理 UNPIVOT 中的 NULL 值

    我可以对表进行逆透视 但结果中不包含空值 create table pivot task age int null a numeric 8 2 b numeric 8 2 c numeric 8 2 d numeric 8 2 e nume
  • 如何让鼠标冻结c#

    我希望鼠标按下时冻结 无法移动 谢谢 我使用了一个tableLayoutPanel供您参考 只需记住将代码实现到前面的Control即可 选项1 重置鼠标位置 定义两个全局变量 bool mousemove true Point curre
  • 如何使用可变模板来展平类型树?

    我有一个这样的构造 template