C++ 有非模板元语言吗?

2024-02-05

我正在阅读 boost::MPL 作者的《c++ 模板元编程》一书。我是 Spirit/phoenix 库的忠实粉丝。

不过我想知道。使用模板进行 C++ 元编程很麻烦。它不是为这种用途而设计的。模板和宏都不支持循环。在模板中,您基本上必须经历递归。

据我了解,c++的编译过程大致是:

  1. 扩展/评估宏
  2. 实例化模板(代码生成)
  3. 然后是实际的其他编译步骤(词法分析、解析、中间代码生成、机器独立优化、生成程序集/目标文件/链接...)

模板元编程是对步骤 1 和 2 的破解,是 20 年前无意中发现的。

使用实际语言不是更简单吗?我的意思是某种可以访问 C++ 语法树并对其进行操作的语言,以及良好的文本处理能力。

我正在考虑像 twig/django 这样的模板语言,以及 g++ AST 的适当挂钩,以及 type_traits 和 pod 类型的本机定义。

这存在吗?我在网上没有找到类似的东西。它可以实现与 C++ 模板元编程相同的结果(甚至更多),但编译速度更快,代码更干净且更具可读性。


你想要的是一个程序转换系统(PTS) http://en.wikipedia.org/wiki/Program_transformation.

这些工具通过以下方式概括了元编程完全超越编程语言(因此,与模板[和您的抱怨]不同,PTS 不限于您可以用编程语言表达的内容)。

一般来说,PTS 通过编程语言语法和漂亮打印规则进行参数化(使其能够将感兴趣的语言 P 解析为 AST,并从 AST 解解析回源代码)、一组转换(代表您所进行的更改的本质)。想要制作,例如“优化数组访问”)和一些“元程序”M,它对如何应用转换进行排序以实现您想要的确切目的(例如,“优化these数组访问但不访问those)".

一个好的 PTS 允许您用嵌入 P 语法的模式语言编写转换。因此,转换本质上是这样表述的:“如果您匹配模式 p,则将其替换为 q”,其中 p 和 q 是代码的表面语法版本出于兴趣。对于基于 AST 的转换规则,任何一种转换都无法完成任意大量的工作(因为模式 AST 是固定直径的),因此需要不止一种转换才能获得复杂的结果。

元程序对转换进行排序;它可以以多种方式编码。 Stratego 在基本转换模式语言的“策略”DSL 扩展中对元程序进行编码,这是对点上转换成功或失败以及树导航步骤(向上、向下、重复)的反应。 TXL 的元程序的功能是通过模式匹配来实现的。 DMS 使用 PARLANSE,一种并行编程语言,它允许在真正大的源代码集上(小心地)并行应用转换。 Clang 没有完整的源模式匹配,但有一些“AST”匹配器,使语法匹配更容易一些;否则,您将转换编写为沿着树向上/向下移动的过程代码,嵌入到用 C++ 本身编码的元程序中。 Rose Compiler 的元程序很大程度上像 Clang 一样是程序性的。有 Eclipse CDT 重构工具;我不太了解它们的状态,但它们没有模式定向转换,而且我认为元程序是用 Java 编写的。还有其他 PTS;他们中的大多数并不像这些那样强大或成熟。 GCC 存在,但并未组织为 PTS。 (对这一切持保留态度;我是 DMS 背后的人,所以你可能不想相信我)。

您特别想要操作 C++。这意味着该工具必须正确处理 C++。 Stratego 和 TXL 目前不支持 C++,并且不太可能,因为需要付出努力才能生成完整的 C++ 前端。 Clang 显然有一个有用的 C++ 前端。 Rose也是如此,因为它使用了EDG前端。 DMS 拥有完整的 C++11 前端,我们在大型 GCC 和 Windows C++ 代码库上构建并验证了该前端。我不确定CDT前端的成熟度;特别是,我不明白他们使用什么作为解析器。

(2015 年 9 月编辑:DMS 现在可以处理 MS 和 GCC 方言中的完整 C++14)。

通过从语言“内部”与“外部”进行元编程,你所交换的是真正神秘的“模板元编程”的可读性,而这些“模板元编程”通常不太神秘的模式语法和元编程语言。恕我直言,您获得了表达能力,因为 PTS 旨在操作源代码,并且它们通常可以调用模板根本无法接近的底层机制(符号表、类型信息、控制/数据流)提供的分析器。

对我来说,真正的优势在于 PTS 可以跨任意代码边界应用转换;大多数C++模板只能生成代码来代替模板调用。 (特别是,在语言内部实现的所有元编程/反射方案的一个缺陷是它们的能力总是受到限制;PTS 没有这样的限制)。

在我的简介中,您可以找到 DMS 描述的链接。更重要的是,那里有一组论文(例如,“案例研究:通过自动程序转换重新设计 C++ 组件模型”),描述了应用于 C++ 程序的大规模转换(将它们从一个具有复杂 API 的 RTOS 转移到完全不同的 RTOS)。系统,以及从根本上重构 API),可以让您体验一下它的样子。 (据我所知,在各种 PTS 工具中,只有 DMS 被应用于如此雄心勃勃的 C++ 转换任务。)这些论文将表明 PTS 操作根本不像模板元编程,不依赖像 SFINAE 这样的技巧,并且恕我直言,可以做任何模板元程序都无法实现的事情。

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

C++ 有非模板元语言吗? 的相关文章

  • 在c中用以下结构填充矩阵

    我有以下结构 typedef struct arr integer int size int arr arr arr integer arr arr integer alloc arr integer int len arr arr int
  • 有没有办法为向量采用内存资源?

    我已经开始在我的项目中使用 pmr allocators 并且我已经看到使用它们带来了很多性能提升和优势 我使用的分配器与我在下面的简单示例中展示的非常相似 include
  • .Net Core 中 String 默认不可序列化吗?

    我正在查看其他的 Fortify 静态分析安全测试 SAST 扫描报告 以识别和抑制误报 应用程序框架是C NET Core SAST 报告部分内容如下 Method1 在第 111 行将不可序列化的对象存储为 HttpSessionSta
  • 请求的资源不支持 HTTP 方法“GET”

    我的路线配置正确 并且我的方法具有装饰标签 我仍然收到 请求的资源不支持 HTTP 方法 GET 消息 System Web Mvc AcceptVerbs GET POST System Web Mvc HttpGet public st
  • 到底什么是“位填充”或“填充位”?

    我只是在互联网上找不到任何关于 位填充 真正含义的详细解释 并且在 Stack Overflow 上也没有找到与位填充相关的线程的任何答案 我还搜索了 ISO 9899 1990 其中提到了 位填充 但没有根据我的需要进行解释 我在网上找到
  • 除了第一列之外,Gridview 行可点击?

    我使用以下代码使 gridview 的整行可单击 protected void gridMSDS RowDataBound object sender GridViewRowEventArgs e if e Row RowType Data
  • 在 C# 中实例化 python 类

    我已经用 python 编写了一个类 我想通过 IronPython 将其包装到 net 程序集中 并在 C 应用程序中实例化 我已将该类迁移到 IronPython 创建了一个库程序集并引用了它 现在 我如何真正获得该类的实例 该类看起来
  • Ruby 解释器嵌入到 C 代码中

    我只是尝试书中的一个简单例子 我有一个 sum rb 文件 class Summer def sum max raise Invalid maximum max if max lt 0 max max max 2 end end 还有一个
  • 根据另一个列表的内容对列表进行排序

    我有一个包含整数列表的列表和另一个包含同时包含整数和字符串的类的列表 我想做的是按字母顺序对列表进行排序 将第一个列表中存在的条目放在前面 这是我的代码和预期输出 using System using System Collections
  • 使用 std::string 导致 Windows“找不到入口点”[重复]

    这个问题在这里已经有答案了 当我用 G C C 编译它时 include
  • 如何在 asp .net mvc 2 中对不直接属于我的模型的对象使用 DisplayFor()?

    我确信我在这里遗漏了一些非常简单的东西 我创建了一个自定义日期时间显示模板 使用以下方法时效果很好 但是 我遇到了这样的情况 在部分控件内 我在 for 循环中迭代模型中的对象 我想要一个 DateTime 属性来使用显示模板 但我不知道如
  • tcmalloc/jemalloc 和内存池之间有什么区别(以及选择的理由)?

    tcmalloc jemalloc是改进的内存分配器 还引入了内存池以更好地分配内存 那么它们之间有什么区别以及在我的应用中如何选择它们呢 这取决于您的程序的要求 如果您的程序有更多的动态内存分配 那么您 需要从可用的分配器中选择一个内存分
  • 如何检查是否发生溢出? [复制]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • 将 libpng 链接到 android 原生项目

    我在尝试在本机 Android 项目中加载 libpng 时遇到问题 编译器似乎无法识别 libpng 函数 但可以识别类型 如 png byte 它可以正常编译类型 但如果我添加函数 则会抛出错误 这是编译输出 Windows 7 cmd
  • 那里有更好的 DateTime.Parse 吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有谁知道有一个库 付费或免费 能够处理比 DateTime Parse 使用的更常见的日期时间格式 能够
  • C++ 静态工厂构造函数

    我正在进行模拟 它需要创建多个相当相似的模型 我的想法是有一个名为 Model 的类并使用静态工厂方法来构造模型 例如 模型 createTriangle or 模型 createFromFile 我从以前的 java 代码中汲取了这个想法
  • 如何在OpenGL中像这样绘制连接的带状线

    我想用以下方式绘制一系列连接线 GL LINE STRIP 我尝试过自己编写代码 但没有得到想要的结果 所以我来到这里 帮助我找出我错在哪里 这里我只给出我的draw 函数 glBegin GL LINE STRIP glVertex2f
  • 为 C++ 类播种 rand()

    我正在开发一个 C 类 它使用rand 在构造函数中 我真的希望这个班级在几乎所有方面都能照顾好自己 但我不知道在哪里播种rand 如果我播种rand 在构造函数中 每次构造我的对象类型的新实例时都会对其进行播种 因此 如果我按顺序创建 3
  • MsBuild 在 Visual Studio Online 上找不到恢复的 NuGet 包

    我尝试构建一个存储在 Visual Studio Online 上的外部 GIT 存储库中的解决方案 它有以下步骤 1 Git 恢复 有效 2 NuGet 恢复 有效 3 构建 不起作用 查看日志时我的第一个猜测是 MsBuild 没有查找
  • GetActiveObject() 与 GetObject() -- MK_E_UNAVAILABLE 错误

    All 我在将一些 VBA 代码转换为 C 时遇到一些问题 我们有一个充当本地 COM 服务器的第 3 方应用程序 在我们使用的VBA代码中获取对象 获取对现有对象的引用 e g Set appHandle GetObject ProgId

随机推荐

  • 未实现委托方法导致崩溃

    我创建了一个协议并将其分配给委托对象 protocol AppBrainDelegate
  • C++ 私有函数真的需要放在头文件中吗?

    我一直认为头文件是一种描述类的 公共接口 在这种情况下 最好将私有字段和函数保留在 cpp 文件中 我知道私有字段需要位于标头中 以便其他类可以知道类的实例将消耗多少内存 但当我即将编写一个私有辅助函数时 我想到可以使该函数成为static
  • 如何防止用户通过写URL直接访问我的html页面?

    我想要一个硬编码的登录页面 登录 html 没有数据库 如果一个人写了正确的用户名和密码 它会重定向到 page2 html 现在我的问题是 如果一个人直接为 page2 html 编写 URL 他将能够访问它 而无需任何登录 理想案例 g
  • 对 JPanel 使用 addMouseListener() 和 PaintComponent()

    这是我的后续previous https stackoverflow com questions 12175174 paintcomponent vs paint and jpanel vs canvas in a paintbrush t
  • Realm 的 kotlin 中的 Android 测试

    如何在 Kotlin 中实现 Android 中领域数据库的简单测试 我尝试改编来自java领域的片段在github上测试 https github com realm realm java blob master examples uni
  • 有没有跨平台的方法来检查 stdout 是否正在通过管道传输到 Rust 中的另一个程序?

    当输出通过管道传输到终端以外的其他地方时 我想禁用颜色 翻译成 POSIX 语言 你的问题将是 stdout 不是 TTY 所以 nix 上的答案可以通过以下方式获得 isatty STDOUT FILENO https stackover
  • 禁止来自 3rd 方 jar 的 java util 日志记录

    我从 Eclipse 控制台中的第 3 方 jar 收到大量信息日志消息 打开 jar 我发现它使用 java util logging 我想将其 jar 的输出级别设置为 警告 我尝试使用 Djava util logging confi
  • JavaFX 会完全取代 Swing 吗?

    我有一个 Java 桌面应用程序 其中图形用户界面是在 swing 中设计的 当我们知道之后JavaFX replacing Swing我们已将图形用户界面替换为 JavaFX 6 JavaFX 是否会取代 Swing 成为 Java 的新
  • 如何在 Nest.js 中提供静态 HTML 文件?

    我想提供静态 HTML 文件 这些文件位于 distNest 项目外部的文件夹 index html加载成功但无法加载任何 JS 文件 404 error 我有一个 Node Express js 项目 它使用 app use expres
  • 在java中获取下一个更高的整数值[重复]

    这个问题在这里已经有答案了 我知道我可以使用 Math java 函数来获取 double 或 float 的下限 上限或舍入值 但我的问题是 如果小数点出现在我的值中 是否可以始终获得更高的整数值 例如 int chunkSize 91
  • silverstripe Sitetree onAfterWrite - renderWith 错误:找不到模板

    为了从页面内容自动生成 pdf 我想在页面类的 onAfterWrite 中使用 renderWith 函数 稍后使用 DOMPDF 将从返回的 HTML 生成 PDF public function onAfterWrite parent
  • 将 UISearchBar 锁定到 UITableView(如 Game Center)的顶部

    Game Center 的 UITableViews 及其顶部的搜索栏有一个很酷的功能 与搜索栏放置在表格标题视图中的应用程序不同 因此它算作标准表格单元格 相反 它似乎固定在其上方的父导航栏上 因此 当滚动表格时 搜索栏确实会移动 但如果
  • 简单堆栈溢出的 Shellcode:带有 shell 的被利用程序在 execve("/bin/sh") 之后直接终止

    我在 Linux amd64 上尝试了缓冲区溢出并尝试利用一个简单的程序 但失败了 我禁用了安全功能 使用 sysctl w kernel randomize va space 0 和 BIOS 中的 nx 位进行地址空间布局随机化 它跳转
  • 带有过滤器参数的 django 自定义管理器

    我想添加一个自定义管理器 它可以从模板调用 但不会影响整个模型 例如管理视图 并且侦听请求中设置的参数 user profile 以下是我到目前为止所拥有的 模型 py class CurrentQuerySet models query
  • 与 crond 不同的 ssh 行为

    我已经在这件事上抓狂了好几个小时了 我欢迎任何有关下一步发展的新想法 目标是通过 SSH 登录到自定义应用程序 CLI 然后使用自定义 CLI 命令之一在远端设备上下拉调试 shell 在客户端 我使用 CentOS mini 并运行 ss
  • 单选按钮的按钮组未使用 Bootstrap 3 设置任何活动按钮

    我正在尝试使用 MVC 和 Bootstrap 3 创建一组漂亮的单选按钮 选择一个选项后 我将值存储在数据库中 但是当我再次呈现视图时 没有选择任何内容 模型是 Table QuotePiecePrinting public partia
  • Mercurial - 如何禁用推送

    我正在尝试寻找是否有一种简单的方法可以使 Mercurial 存储库变为只读 用户应该能够克隆 但不允许推送 我需要对超过 100 个的所有存储库执行此操作 你可以在 hg hgrc 中这样做 hooks prechangegroup fa
  • 默认将没有扩展名的文件分配给 VS Code 上的语言

    在 VS Code 中 我通常打开没有扩展名的文件filename 我知道我可以更改语言语法更改语言模式 gt 我想要的语言但我不想每次打开这样的文件时都手动执行此操作 每次打开没有扩展名的文件时是否可以默认使用该语言 我知道我可以这样做
  • 如何使用curl从pod内访问Kubernetes API?

    我在 Google Kubernetes Engine 上使用 Kubernetes 1 8 6 并有一个运行 Alpine 的 Pod 作为StatefulSet 我已使用以下方式登录我的 podkubectl exec it my po
  • C++ 有非模板元语言吗?

    我正在阅读 boost MPL 作者的 c 模板元编程 一书 我是 Spirit phoenix 库的忠实粉丝 不过我想知道 使用模板进行 C 元编程很麻烦 它不是为这种用途而设计的 模板和宏都不支持循环 在模板中 您基本上必须经历递归 据