草庐IT

c++ - 设计用于标记和传输树的 C++ DSL

coder 2024-02-26 原文

简而言之

我正在尝试为 C 库设计一个更好的 C++ 接口(interface),它通过通信 channel 发送树状表达式(à la iostreams vs stdio)。我不确定是否有可能在 C++ 中设计一个 DSL 来标记这些树同时避免运行时开销,如果是的话,如何。

C库的简单解释

有一个 C 库可以通过通信 channel 发送“表达式”。这里的“表达式”是指树结构,可以用类似于函数调用的方式方便地表示。

例如,

f(1, 2, g(3), "foo")

表示这棵树:

你们中的一些人可能认识 Mathematica在这一点上,但我决定将其排除在外,因为它与问题无关。

我们将 f 称为 head12g(3) 作为参数

要发送此表达式,我们将编写以下内容:

putHead("f" /* name */, 3 /* argument count */);
  putInteger(1);
  putInteger(2);
  putHead("g" /* name */, 1 /* argument count */);
    putInteger(3);
  putString("foo");

问题

是否可以为此设计一个具有以下特点的更方便的C++ API?

  1. 编写起来更简洁(想想 iostreams vs stdio)
  2. 无需为每个头显式指定参数计数;取而代之的是使用一种方便的表示法(类似于上面的 f(1,2,g(3))),它从中自动推断参数计数
  3. 在没有运行时开销的情况下实现 (2)(即在编译时推断参数计数)
  4. 必须在后台使用上述 C 接口(interface)

我可以使用类似流的接口(interface)来执行 (1)(即无需明确指定每个参数的 Integer、String 等类型)。我可以以涉及额外运行时计算的方式执行 (2)。但我不知道考虑到 C++ 的特性,(2)/(3) together 是否可能。最后,我希望在 C++ 本身中为这些表达式提供一个方便的符号。

那么是否有可能在 C++ 中为此设计一个 DSL,同时避免所有运行时开销?如果是,如何?我不一定要寻找以代码为答案的完整解决方案,只是寻找一些入门指南或可能有效的方法摘要。

最佳答案

我可以想出几种在 C++ 中表示树的方法。其中一些(#1、#2)的实现将涉及构建一个中间结构,然后在最后调用 C 函数。其他人(#5、#6)可以随时调用 C 函数,因为在编译时已知任何节点的子节点数。

1) 使用流畅的接口(interface)和重载:

Tree()
  .head("f")
    .put(1)
    .put(2)
    .head("g")
      .put(3)
      .end()
    .put("foo")
    .end();

2) 或者,不调用 end():

head("f")
  .put(1)
  .put(2)
  .put(head("g")
    .put(3))
  .put("foo");

3) 使用运算符<>

Tree("f")
  << 1
  << 2
  << (Tree("g") << 3)
  << "foo";

4) 使用运算符():

Tree("f")
  (1)
  (2)
  (Tree("g")(3))
  ("foo")

5) 使用 std::initializer_list,其中 Node 是一种可从 int 和 std::string 隐式转换的类型:

Tree { "f", {
  1,
  2,
  { "g", { 3 } }
  "foo",
} }

6) 使用可变参数模板:

head("f").put(
  1,
  2,
  head("g").put(3)
  "foo");

关于c++ - 设计用于标记和传输树的 C++ DSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35970776/

有关c++ - 设计用于标记和传输树的 C++ DSL的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  5. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  6. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  7. ruby - 如何在 Ruby 中创建无类 DSL? - 2

    我正在尝试找出如何为我的Ruby项目创建一种“无类DSL”,类似于在Cucumber步骤定义文件中定义步骤定义或在Sinatra应用程序中定义路由。例如,我想要一个文件,其中调用了我的所有DSL函数:#sample.rbwhen_string_matches/hello(.+)/do|name|call_another_method(name)end我认为用我的项目特有的一堆方法污染全局(内核)命名空间是一种不好的做法。因此方法when_string_matches和call_another_method将在我的库中定义,并且sample.rb文件将以某种方式在我的DSL方法的上下文中

  8. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  9. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  10. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

随机推荐