【问题标题】:Example of using the ## preprocessor operator使用 ## 预处理器运算符的示例
【发布时间】:2021-03-01 23:04:04
【问题描述】:

我知道以下是一个非常简单的示例,但是我如何将以下内容转换为使用预处理器 ## 'glue' 运算符的单个函数调用?

void print_string(char *s)
{
    printf("%s\n", s);
}
void print_num(int n)
{
    printf("%d\n", n);
}

int main(void)
{
    print_string("Hello");
    print_num(5);
}

我唯一能做的(这并没有真正简化任何事情)是:

#define PRINT(type) print_ ## type
PRINT(string)("Hello");
PRINT(num)(4);

或者,有没有更好的方法来使用它?

【问题讨论】:

  • 从 C11 尝试 _Generic?
  • @tstanisl 谢谢,你能举个例子吗?我以前从未使用过那种类型(?)。
  • 你不能用预处理器做到这一点。预处理器处理编译时值,而不是运行时值。
  • 您可以使用预处理器执行此操作,但不能完全使用您显示的语法。你会接受需要 PRINT(string, "Hello"); 而不是 PRINT(string)("Hello"); 的语法吗?

标签: c c-preprocessor


【解决方案1】:

您可以将标识作为第一个函数参数:

#define PRINT(type, value)   print_ ## type(value)
PRINT(string, "Hello");
PRINT(num, 4);

但我认为写printf 没有任何价值,因为有人必须学会写num,以防int,他还不如学习使用%d

printf("%s\n", "Hello");
printf("%d\n", 4);

pre 处理器中不可能进行类型分派 - 它不知道类型。在 C11 中有 _Generic 允许编译器根据类型选择不同的函数:

#define PRINT(value) _Generic((value), \
        char *: print_string, \
        int: print_int)(value)
PRINT("Hello");
PRINT(4);

通过在每个参数上重载宏并在每个参数上应用这样的_Generic 宏,可以构建 C++ std::cout 的替代品。所以有点自我推销:这是我在yio library 中探讨的一个主题,它允许这样做:

yprint("Hello ", 4, "\n");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 2018-06-09
    • 2011-06-14
    • 2015-11-11
    相关资源
    最近更新 更多