使用预处理器生成具有多个参数的显式实例化

2024-01-07

在我的项目中,我希望对模板化函数进行大量显式实例化,以减少构建时间。现在我有很多函数,它们可以有不同的模板。出于这个原因(如果我想要更多)我不想手动输入它们,而是让预处理器生成它们。

我想要生成的示例:

template bool match_any<x>();
template bool match_any<y<x>>();
template bool match_expr<x,y,z>();

whereas x是 1 和定义之间的整数max_dim, y可以是三个值之一:real, bool, index and z是 0 或 1。

我现在想生成这三个函数与参数的任何可能的组合(例如 template bool match_any<0>(); template bool match_any<1>(); template bool match_any<2>(); ...),但不仅限于这些,因为我有大约 100 个具有类似结构的函数。

Through 使用宏定义前向声明 https://stackoverflow.com/questions/74043745/using-macros-to-define-forward-declarations我已经弄清楚如何做重复模式:

#define REP_INT_1(f) f(1)
#define REP_INT_2(f) REP_INT_1(f) f(2)
#define REP_INT_3(f) REP_INT_2(f) f(3)
#define REP_INT_4(f) REP_INT_3(f) f(4)

#define REP_INT(n,gen) REP_INT_(n,gen)
#define REP_INT_(n,gen) REP_INT_##n(gen)

然后我可以使用它

#define GEN(x) template bool match_any<x>();
REP_INT(3, GEN)
#undef GEN

当然,重复这种模式很简单,例如对于字符串。

但我现在的问题是,由于模式的本质(当我通过GEN作为一个“函数”)我不能为 GEN 提供两个参数。当然,我可以改变重复模式,这样它也适用于两个参数,但随后我必须为任意数量的参数以及它们的每个顺序创建一个像这样的新模式,这最终会达到目的,因为我将为每个函数设置一个大块 - 然后我可以手动编写它。

有谁知道如何通过不同的方式“循环”可能的参数或如何扩展我现有的方法以使其适用于多个参数来实现此目的?


您可以像这样添加到宏中以获得某种可维护的列表:

#define GEN_X(f) REP_INT(3, f)
#define GEN_Y(f, x) f(x, real) f(x, bool) f(x, index)
#define GEN_Z(f, x, y) f(x, y, 0) f(x, y, 1)

// GEN_F3 = generate functions with at least 3 arguments
#define GEN_F3(x, y, z) template bool match_any<x, y, z>();
#define GEN_F2(x, y) template bool match_any<y<x>>(); GEN_Z(GEN_F3, x, y)
#define GEN_F1(x) template bool match_any<x>(); GEN_Y(GEN_F2, x)
GEN_X(GEN_F1)

demo http://coliru.stacked-crooked.com/a/785dfa5889d1e931

我们将变量生成器分开,然后将它们链接在一起以获得所有排列:您的宏生成x的,通过管道输送到GEN_F1,它处理单参数情况并通过管道传输这些x值对y- 发电机等。

请注意,尽管我们已经使源代码可线性维护,但我们无法避免可执行文件大小的指数级增长。


为了解决您的扩展问题,如果您希望能够处理两个参数的数字的任何排列,例如 x={1,2,3}, y={1,2,3,4},直观上您可能想要像这样调整:

#define GEN_X(f) REP_INT(3, f)
#define GEN_Y(f, x) REP_INT(4, f)

这几乎可行,但宏扩展阻止在一次递归扩展中再次使用相同的 REP_INT_* 宏(至少以我所做的方式)。

一种解决方法是有两个REP_INT列表(其中至少一个需要处理可变输入,将数字附加到末尾)。宏可以相同,只是名称需要不同才能继续扩展。

然后我们可以像这样解决扩展问题:

#define GEN_X(f) REP1_INT_3(f)
#define GEN_Y(f, x) REP2_INT_4(f, x)

#define GEN_F2(x, y) template bool match_any<x, y>();
#define GEN_F1(x) GEN_Y(GEN_F2, x)
GEN_X(GEN_F1)

demo http://coliru.stacked-crooked.com/a/3ad685e44d95b927

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

使用预处理器生成具有多个参数的显式实例化 的相关文章

  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐