【问题标题】:C/C++ macro parameter containing dot (member access operator)包含点的 C/C++ 宏参数(成员访问运算符)
【发布时间】:2020-02-09 06:19:51
【问题描述】:

如何在 C/C++ 宏中使用包含点(成员访问运算符)的参数?

例子:

#define M(obj,y) obj.y##x
struct S { struct {int x;} c; int x; };
S s;
s.c.x = 1;
s.x = 2;
M(s,)   // works, 2 (resolves to s.x)
M(s,c.) // error: pasting formed '.x', an invalid preprocessing token

如何让M(s,c.) 解析为s.c.x?

感谢您的帮助!

【问题讨论】:

  • 您使用的是 C 还是 C++?如果您使用的是 C++,我建议您放弃宏并制作模板函数。
  • 宏往往会使代码更难阅读、理解和维护。尤其是像您想要制作的宏。请尽量避开它们。
  • 感谢您的 cmets!不过,有可能吗?
  • 你可能需要另一个间接层,就像使用 concat 宏所做的那样。我不是宏专业人士,所以它可能无济于事。
  • . 的两侧(或两侧)可以有空格。

标签: c++ c arguments c-preprocessor member-access


【解决方案1】:

令牌粘贴运算符## 要求其两个操作数是有效的预处理令牌,并产生一个预处理令牌。它通常用于将两个标识符连接成一个标识符。

您在这里尝试做的不是令牌粘贴。相反,您正在寻求创建像s.x 或s.c.x 这样的表达式,其中x 部分始终是单个标记。因此,不应使用## 运算符。相反,您可以这样做:

#define M(obj, y) obj.y x

当您尝试使用## 运算符时,预处理器会尝试将参数y 中的最后一个标记与标记x 结合起来。在c.中,.是一个token,所以结果是.x,它不是一个合法的token。相反,.x 仅作为两个标记的序列有效。

【讨论】:

  • 如果您使用箭头运算符,这也适用 ->
猜你喜欢
  • 2016-06-15
  • 1970-01-01
  • 2011-06-11
  • 2015-12-18
  • 2021-05-29
  • 1970-01-01
  • 2020-12-16
  • 1970-01-01
  • 2013-02-02
相关资源
最近更新 更多