Sza*_*lcs 5 c++ dsl templates api-design notation
我正在尝试为 C 库设计一个更好的 C++ 接口,该库通过通信通道(à la iostreams vs stdio)发送树状表达式。我不确定是否有可能在 C++ 中设计一个 DSL 来标记这些树,同时避免运行时开销,如果是,如何。
有一个 C 库可以通过通信通道发送“表达式”。这里的“表达式”是指可以方便地以类似于函数调用的方式表示的树结构。
例如,
f(1, 2, g(3), "foo")
Run Code Online (Sandbox Code Playgroud)
表示这棵树:

你们中的一些人此时可能认识Mathematica,但我决定将其排除在外,因为它与问题无关。
我们指的f是头和1,2,g(3)为参数。
要发送此表达式,我们将编写以下内容:
f(1, 2, g(3), "foo")
Run Code Online (Sandbox Code Playgroud)
是否可以为此设计一个具有以下功能的更方便的 C++ API?
iostreamsvs stdio)f(1,2,g(3))上面的),从中它自动推断参数计数我可以用一个类似流的接口来做(1)(即不需要显式指定每个参数的整数、字符串等的类型)。我可以以涉及额外运行时计算的方式执行 (2)。但我不知道考虑到 C++ 的特性,(2)/(3)是否可以一起使用。最终,我希望在 C++ 本身中为这些表达式提供一个方便的符号。
那么是否有可能在 C++ 中为此设计 DSL,同时避免所有运行时开销?如果是,如何?我不一定要寻找以代码为答案的完整解决方案,只是一些入门指南,或者可能有效的方法的摘要。
我可以想到几种在 C++ 中表示树的方法。其中一些(#1、#2)的实现将涉及构建中间结构,然后在最后调用 C 函数。其他人(#5、#6)可以随时调用 C 函数,因为任何节点的子节点数量在编译时都是已知的。
1)使用流畅的接口和重载:
Tree()
.head("f")
.put(1)
.put(2)
.head("g")
.put(3)
.end()
.put("foo")
.end();
Run Code Online (Sandbox Code Playgroud)
2) 或者,不调用 end():
head("f")
.put(1)
.put(2)
.put(head("g")
.put(3))
.put("foo");
Run Code Online (Sandbox Code Playgroud)
3)使用运算符<<:
Tree("f")
<< 1
<< 2
<< (Tree("g") << 3)
<< "foo";
Run Code Online (Sandbox Code Playgroud)
4)使用运算符():
Tree("f")
(1)
(2)
(Tree("g")(3))
("foo")
Run Code Online (Sandbox Code Playgroud)
5) 使用 std::initializer_list,其中 Node 是可从 int 和 std::string 隐式转换的类型:
Tree { "f", {
1,
2,
{ "g", { 3 } }
"foo",
} }
Run Code Online (Sandbox Code Playgroud)
6)使用可变参数模板:
head("f").put(
1,
2,
head("g").put(3)
"foo");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
194 次 |
| 最近记录: |