【问题标题】:C++ Macro's Token-Paster as argument of a functionC++ 宏的 Token-Paster 作为函数的参数
【发布时间】:2016-09-28 04:16:38
【问题描述】:

我在网上搜索了一段时间,不幸的是我没有找到我的问题的答案或解决方案,事实上,假设我有 2 个这样命名的函数:

1) function1a(some_args)

2) function2b(some_args)

我想做的是编写一个宏,当输入正确的参数时,它可以识别这些函数,只是问题是,这个参数也应该是 C/C++ 函数的参数,这就是我所做的到目前为止。

 #define FUNCTION_RECOGNIZER(TOKEN) function##TOKEN()

void function1a() 
{

}
void function2a() 
{
}

void anotherParentFunction(const char* type)
{
    FUNCTION_RECOGNIZER(type);
}

显然,宏正在识别“functiontype”并忽略 anotherParentFunction 的参数,我在问是否存在/存在技巧或任何东西来执行这种粘贴方式。

提前谢谢你:)

【问题讨论】:

  • 你应该使用函数重载而不是宏。只需给 function1a 和 function1b 赋予相同的名称:function1。
  • 我想避免重载并在不使用它的情况下找到解决方案。
  • 对于这个任务重载是很自然的方法,必须使用。宏不是为此而不能使用的,因为宏不知道类型。
  • 你是不是认为如果你打电话给anotherParentFunction("1a"),那么你最终会打电话给function1a(),但是如果你打电话给anotherParentFunction("2a"),你最终会打电话给function2a()?如果是这样,那么您很遗憾地误解了 C++ 预处理器的操作。这是一个运行时决定,不能由预处理器编码——例如,如果你使用包含用户提供的数据的变量而不是字符串文字,那就更不行了。
  • @JonathanLeffler 只要在编译时知道这些值,就有可能。

标签: c++ macros


【解决方案1】:

如果您坚持使用宏:跳过 anotherParentFunction() 函数并直接使用宏。当使用常量字符串调用时,即

FUNCTION_RECOGNIZER( "1a");

它应该可以工作。

更类似于 C++ 的解决方案是,例如使用枚举,然后以枚举作为参数和调用相应函数的开关来实现 anotherParentFunction()。当然,每次添加新函数时都需要更改枚举和 switch 语句,但在选择函数名称时会更灵活。

还有更多的解决方案可以实现类似的目标,真正的问题是:您的用例是什么?想要达到什么目的?

【讨论】:

    【解决方案2】:

    在 16.1.5 标准中说:

    实现可以有条件地处理和跳过源文件的部分,包括其他源文件,并替换宏。 这些功能称为预处理,因为从概念上讲,它们发生在翻译结果翻译单元之前。

    [强调我的]

    最初的预处理是由一个单独的应用程序完成的,它本质上是一种独立的语言。

    如今,预处理器通常是编译器的一部分,但是 - 例如 - 您在 Clang AST 树中看不到宏等。

    这样做的意义在于预处理器对类型、函数或参数一无所知。

    你的函数定义

    void anotherParentFunction(const char* type)
    

    对预处理器没有任何意义,被它完全忽略。

    FUNCTION_RECOGNIZER(type);
    

    这被识别为已定义的宏,但 type 不是可识别的 预处理器 符号,因此它被视为文字,预处理器不咨询 C++ 解析器或交互用它的 AST 树。

    它查阅宏定义:

    #define FUNCTION_RECOGNIZER(TOKEN) function##TOKEN()
    

    参数,字面量type,被标记为TOKEN。单词function 被视为文字并复制到结果字符串中,## 告诉处理器复制标记TOKEN 的值,在结果字符串中生成functiontype。因为TOKEN 未被识别为宏,所以()s 结束标记,() 作为文字附加到结果字符串。

    因此,预处理器替换

    FUNCTION_RECOGNIZER(type);
    

    functiontype();
    

    所以坏消息是,没有办法做你想做的事,但这可能是XY Problem,也许有一个解决方案来解决你想做的事情。

    例如,可以根据参数类型重载函数,或者根据参数专门化模板函数,或者您可以根据参数值创建查找表。

    【讨论】:

      猜你喜欢
      • 2015-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多