基于 C++ 的 DSL,支持使用带有参数列表的运算符[]

问题描述 投票:0回答:1

我需要用 C++ 编写一个自定义 DSL,用于定义 Pokémon、能力、向特定 Pokémon 教授能力,然后模拟决斗。到目前为止,我已经成功地使大部分 DSL 按照描述的方式工作,但我很难实现以下代码:

DEAR "Pikachu" LEARN [
    ABILITY_NAME(Electric_Shock)
    ABILITY_NAME(Lightning_Rod)
]

此 DSL 代码基本上应该转换为有效的 C++ 代码,该代码向 DEAR 宏之后指定的 Pokémon 传授指定的能力。到目前为止,我为此特定部分所做的工作如下:

/**
 * \brief 
 */
#define DEAR ; (*getPokemonByName(
/**
 * \brief 
 */
#define LEARN ))

/**
 * \brief Retrieves the ability with the given name, if it exists.
 * Otherwise, nullptr is returned.
 * \param name The name of the ability to look for.
 */
#define ABILITY_NAME(name) getAbilityByName(#name)

如果存在给定名称(在 DEAR 宏之后)的 Pokémon,则

getPokemonByName()
返回
Pokemon*
,否则返回
nullptr
(我将在稍后访问
nullptr
之前发出错误并终止)。同样的逻辑适用于
getAbilityByName()
函数,该函数又返回
SingleAbilityExpr*

我的思考过程是想出一种方法,将

SingleAbilityExpr*
中的各种
[]
组合成一个,然后在神奇宝贝类中重载
operator[]
,以便向所选神奇宝贝传授能力。问题是我无法找到一种方法来使用这种特定的语法来破解此功能。除了我的方法之外,还有其他方法可以实现我想要的吗?

最初,我希望如果

ABILITY_NAME
宏最后发出
,
,我可以重载
operator,
类中的
SingleAbilityExpr
,从而以这种方式收集它们。遗憾的是,由于最后一个尾随逗号,这似乎不起作用,我发现无法使用 c++11 来使用它。

c++ c++11 c-preprocessor
1个回答
0
投票

C++23 添加了多参数

operator[]
,但在你的情况下没有用,因为你最终会得到以下结果:(在
ABILITY_NAME
添加逗号后)

foo[
    getAbilityByName("a"),
    getAbilityByName("b"),
    getAbilityByName("c"),
]

这没有用,因为结尾的逗号是错误的。

相反,你应该这样做

#define ABILITY_NAME(name) +getAbilityByName(#name)
,其中
getAbilityByName()
返回一个能力列表(可能是
std::vector
的包装),并带有重载的运算符:

  • Unary
    +
    ,返回列表不变,并且
  • 二进制
    +
    ,连接列表。

然后

operator[]
应该接受列表作为唯一的参数:

foo[
    +getAbilityByName("a") // Unary +
    + getAbilityByName("b") // Binary +
    + getAbilityByName("c") // Binary +
]
© www.soinside.com 2019 - 2024. All rights reserved.