C++ 和 D 中的元编程

2023-12-31

C++ 中的模板机制只是意外地对模板元编程有用。另一方面,D 是专门为促进这一点而设计的。显然它更容易理解(或者我听说过)。

我没有使用 D 的经验,但我很好奇,当涉及到模板元编程时,在 D 中可以做什么而在 C++ 中不能做什么?


在 D 中帮助模板元编程的两个最重要的事情是模板约束和static if- 从理论上讲,C++ 可以添加这两者,并且这将使其受益匪浅。

模板约束允许您在模板上放置一个条件,该条件必须为真才能实例化模板。例如,这是其中一位的签名std.algorithm.find的重载:

R find(alias pred = "a == b", R, E)(R haystack, E needle)
    if (isInputRange!R &&
        is(typeof(binaryFun!pred(haystack.front, needle)) : bool))

为了能够实例化此模板化函数,类型R必须是由下式定义的输入范围std.range.isInputRange (so isInputRange!R必须是true),并且给定的谓词需要是一个二元函数,它使用给定的参数进行编译并返回一个可以隐式转换为的类型bool。如果模板约束条件的结果是false,那么模板将无法编译。这不仅可以保护您免受在 C++ 中模板无法使用给定参数进行编译时出现的令人讨厌的模板错误的影响,而且还可以使您可以根据模板约束重载模板。例如,还有另一个过载find这是

R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if (isForwardRange!R1 && isForwardRange!R2
        && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool)
        && !isRandomAccessRange!R1)

它采用完全相同的参数,但其约束不同。因此,不同的类型使用同一模板化函数的不同重载,并且最佳实现find可用于每种类型。在 C++ 中没有办法干净地完成这类事情。只要稍微熟悉一下典型模板约束中使用的函数和模板,D 中的模板约束就相当容易阅读,而您需要在 C++ 中进行一些非常复杂的模板元编程才能尝试这样的事情,而普通程序员却做不到这一点都能够理解,更不用说自己亲自去做了。 Boost 就是一个典型的例子。它做了一些令人惊奇的事情,但它非常复杂。

static if进一步改善情况。就像模板约束一样,任何可以在编译时评估的条件都可以与它一起使用。例如

static if(isIntegral!T)
{
    //...
}
else static if(isFloatingPoint!T)
{
    //...
}
else static if(isSomeString!T)
{
    //...
}
else static if(isDynamicArray!T)
{
    //...
}
else
{
    //...
}

哪个分支被编译取决于哪个条件首先评估为true。因此,在模板中,您可以根据模板实例化的类型或基于可以在编译时评估的任何其他内容来专门化其实现的各个部分。例如,core.time uses

static if(is(typeof(clock_gettime)))

根据系统是否提供不同的方式编译代码clock_gettime或不(如果clock_gettime在那里,它使用它,否则它使用gettimeofday).

我见过的 D 对模板进行改进的最明显的例子可能是我的团队在工作中在 C++ 中遇到的一个问题。我们需要根据给定的类型是否派生自特定基类来以不同的方式实例化模板。我们最终使用了基于的解决方案这个堆栈溢出问题 https://stackoverflow.com/questions/2631585/c-how-to-require-that-one-template-type-is-derived-from-the-other。它有效,但仅测试一种类型是否派生于另一种类型是相当复杂的。

然而,在 D 中,您所要做的就是使用:操作员。例如

auto func(T : U)(T val) {...}

If T可以隐式转换为U(就像如果T源自U), then func将编译,而如果T不能隐式转换为U,那么就不会了。That简单的改进甚至可以使基本的模板专业化变得更加强大(即使没有模板约束或static if).

就我个人而言,除了容器和偶尔使用的函数之外,我很少在 C++ 中使用模板<algorithm>,因为它们使用起来非常痛苦。它们会导致丑陋的错误,并且很难做任何花哨的事情。要完成任何稍微复杂的事情,您都需要非常熟练地使用模板和模板元编程。不过,有了 D 中的模板,它非常简单,我一直在使用它们。这些错误更容易理解和处理(尽管它们仍然比非模板化函数通常出现的错误更糟糕),而且我不必弄清楚如何通过花哨的元编程强制语言执行我想要的操作。

C++ 没有理由不能获得 D 所拥有的大部分能力(如果它们能够解决这些问题,C++ 概念将会有所帮助),但直到它们添加了类似于模板约束和构造的基本条件编译和static if对于 C++,C++ 模板在易用性和功能方面无法与 D 模板相比。

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

C++ 和 D 中的元编程 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags

随机推荐

  • 类内递归

    我试图在类语句中放置一个递归公式 class SomeNode def init self a leng len a half leng 2 self firstnode a 0 0 self child1 SomeNode a i for
  • 从外部连接到在 docker 容器内运行的服务

    我有一个服务在 docker 容器 本地机器 中运行 我可以在 Ambari 服务配置中看到服务 URL 现在我想使用本地开发环境连接到该服务 我发现我可以连接到容器内的该 URL 但是当我在本地外部使用该 URL 时 连接被拒绝 Caus
  • 为什么 vector 不是 STL 容器?

    Scott Meyers 的书第 18 条有效的 STL 改进标准模板库使用的 50 种具体方法说要避免vector
  • 专门化主模板时,更专门化意味着什么?

    C 模板特化规则中提到的特化必须比主模板更加特化 下面的 1 代码片段会导致编译错误 这表明第二行并不更专业 但最后一个片段 2 的工作看起来非常接近 1 两个代码片段都是专门的int N as 0 那么为什么第一个片段被抱怨为 不更专业
  • spect.getmembers() 与 __dict__.items() 与 dir()

    谁能用足够的例子向我解释黑白有什么区别 gt gt gt import inspect gt gt gt inspect getmembers 1 and gt gt gt type 1 dict items and gt gt gt di
  • 创建 SwiftUI 侧边栏

    我想使用 SwiftUI 构建一个非常简单的 iOS 14 侧边栏 设置很简单 我有三个视图HomeView LibraryView and SettingsView和代表每个屏幕的枚举 enum Screen Hashable case
  • jquery blockUI 判断页面或特定元素是否被阻止

    有没有办法判断 blockUI 是否有效已被调用但 unblockUI 尚未被调用 理想情况下 这应该能够阻止整个页面和特定元素 我希望它能像这样工作 gt blockUI gt isBlockUI gt gt true gt unbloc
  • HTML5 文档中的多个

    使用多个可以吗
  • WPF 网格不显示滚动条

    在 NET 3 5 中 我在窗口中有一个网格 我正在用按钮填充这个网格 当按钮填满网格并消失时 网格不会显示滚动条 我已将网格垂直滚动设置为可见 但它仍然不显示
  • 如何围绕特定点来回旋转物体?

    我正在使用 Raphael JS 尝试围绕中心点下方的点旋转图像形状 如何才能做到这一点 我已经尝试过以下方法 但它不起作用 var playBBox playButtonRef getBBox var xPos playBBox x pl
  • Spring Boot - 从依赖 jar 加载 application.properties/yml

    我有一个 Spring Boot 应用程序 我想按特定顺序将值注入到 ConfigurationProperties bean 中 例如 ConfigurationProperties myproperties class MyProper
  • 获取资源管理器窗口排序的字段

    我想知道是否有办法知道 Windows 资源管理器窗口中的文件是如何排序的 有点像窗口的 ORDER BY 子句 示例 名称升序 或 修改日期降序 这个问题不是关于 Windows 的名称排序算法 而是关于特定打开的 Windows 资源管
  • RVO(返回值优化)适用于所有对象吗?

    Is RVO 返回值优化 http en wikipedia org wiki Return value optimization 保证或适用于 C 编译器 特别是 GCC 中的所有对象和情况 如果答案是 否 那么类 对象的这种优化的条件是
  • 将命令行参数传递给随 Poetry 安装的 Python 脚本

    诗歌文档 https python poetry org docs pyproject scripts表示脚本部分可用于在安装包时安装脚本或可执行文件 但它没有显示任何如何将参数传递给脚本的示例 您如何才能接收argparse函数中的参数
  • IntelliJ JDK 16 抢先体验 - 有成功吗?工具.jar

    有没有人使用 JDK 16 取得过成功 https jdk java net 16 https jdk java net 16 使用 IntelliJ 进行早期访问构建 我能够使用 JDK 15 早期访问版本 但是当我尝试 JDK 16 时
  • 删除一项内的内容时在行上方创建神秘空间

    我有一个包含一些项目的网格 当我单击任何项 目时 我会将该项目的内容移动到模式中 该模式效果很好 但是当我从项目中删除内容时 项目上方会出现一个空格 我知道解决这个问题的方法可能是使用弹性盒 它工作得很好 但我想了解这里发生了什么 这里可能
  • CSS3 高度 100%

    我不知道如何问 写这个 所以请随时更新名称或指出正确的问题 标题 我正在设计一个跨 html5 css3 网站 并试图使其在每个 常见 浏览器上看起来都相同 这就是我所拥有的 http www pojotlan com example1 h
  • ProgressBars 和 Espresso

    当我在运行一些浓缩咖啡测试时显示的布局中有一个进度条时 然后我遇到 Caused by android support test espresso AppNotIdleException Looped for 1670 iterations
  • 在调试之前尝试启动带有任务的服务器时出现“无法跟踪指定的任务”

    我的调试配置如下launch json type node request attach preLaunchTask npm start name Attach port 9090 这是定义在中的任务tasks json type npm
  • C++ 和 D 中的元编程

    C 中的模板机制只是意外地对模板元编程有用 另一方面 D 是专门为促进这一点而设计的 显然它更容易理解 或者我听说过 我没有使用 D 的经验 但我很好奇 当涉及到模板元编程时 在 D 中可以做什么而在 C 中不能做什么 在 D 中帮助模板元