事实上,我不知道如何非常精确。
今天,我浏览了以下页面:
http://siliconframework.org/docs/hello_world.html
我找到了以下语法:
GET / _hello = [] () { return D(_message = "Hello world."); }
我发现"GET"可以通过lambda表达式成为函数,但我无法弄清楚"/"和"_hello"在这里是什么意思,以及它们如何连接到有意义的东西。
另外,那个"_message="是什么?
顺便说一句,我的主要C++知识是在 C++11 之前。
我用谷歌搜索了很多。
谁能给出一个解释?
该库使用所谓的嵌入式域特定语言,它扭曲C++和预处理器语法,允许看似不同的语言只是C++程序的另一部分。
简而言之,魔法。
第一个魔力在于:
iod_define_symbol(hello)
这是一个宏,用于生成类型为_hello_t
的标识符_hello
。
它还创建一个继承自名为iod::symbol<_hello_t>
的 CRTP 帮助程序的_hello_t
类型。
_hello_t
覆盖各种运算符(包括operator=
和operator/
),使它们不执行您通常期望C++对象的行为。
GET / _hello = [] () { return D(_message = "Hello world."); }
所以这个调用
operator=(
operator/( GET, _hello ),
/* lambda_goes_here */
);
同样在 lambda 中:
D(_message = "Hello world.");
是
D( operator=(_message, "Hello world.") );
operator/
和operator=
几乎可以做任何事情。
在D
的情况下,=
不做任何赋值——相反,它构建了一个结构,基本上说"名为"message"
的字段被分配了值"Hello world."
。
_message
知道它被称为"message"
,因为它是由一个宏iod_define_symbol(message)
生成的,他们message
字符串并将其与类型_message_t
一起存储,并创建了变量_message
该类型的实例。
D
采用许多这样的键/值对并将它们捆绑在一起。
lambda 返回此捆绑包。
所以[] () { return D(_message = "Hello world."); }
是一个 lambda,它返回一堆键值对附件,以一种奇怪的方式编写。
然后,我们使用左侧的GET/_hello
调用operator=
。
GET
是另一个全局对象,其上operator/
重载。 我还没有追查到它。 假设它是iod::get_t
型(我编造了这个名字:同样,我没有查过它是什么类型,这并不重要)
然后iod::get_t::operator/(iod::symbol<T> const&)
重载以生成另一个帮助程序类型。 此类型获取T
的名称(在本例中为"hello"
),并等待 lambda 将其分配给它。
分配到时,它不会执行您的预期操作。 相反,它会关闭并在"hello"
和调用该 lambda 之间建立关联,其中该 lambda 应返回一组由D
生成的键值对。
然后我们将一个或多个这样的关联传递给http_api
,收集这些捆绑包并构建使用这些查询和响应运行 Web 服务器所需的数据,可能包括说"我要成为 http 服务器"的标志。
然后sl::mhd_json_serve
获取这些数据和端口号,并实际运行Web服务器。
所有这些都是一堆抽象层,以使一些反射更容易。 生成的结构都具有C++标识符和类似的字符串。 其中公开了类似的字符串,当生成 json 序列化(或反序列化)代码时,这些字符串用于读取/写入 json 值。
宏的存在只是为了使编写样板更容易。
如果您想了解此处发生的事情,可能有助于进一步阅读的技术包括"表达式模板"、"反射"、"CRTP"、嵌入式"领域特定语言"。
上面的一些包含一些小的"告诉孩子的谎言" - 特别是,运算符语法不像我暗示的那样工作。 (a/b
不等同于operator/(a,b)
,因为第二个不会调用成员运算符/
。 理解它们只是函数是我的意图,而不是语法是相同的。
@mattheiuG(该框架的作者)在这篇文章下方的评论中分享了这些幻灯片,进一步解释了D
以及_message
令牌和框架。
它不是标准的语法C++而是特定于框架的。以下划线(_hello
、_message
等)为前缀的元素与符号定义生成器一起使用,该生成器在编译之前运行并创建必要的定义。
本页末尾有更多信息:http://siliconframework.org/docs/symbols.html。Qt
用它的moc
工具做了类似的事情。