繁体   English   中英

使用C ++宏检查变量存在

[英]Using C++ Macros To Check For Variable Existence

我正在为我的库创建一个日志记录工具,并制作了一些很好的宏,例如:

#define DEBUG  myDebuggingClass(__FILE__, __FUNCTION__, __LINE__)
#define WARING myWarningClass(__FILE__, __FUNCTION__, __LINE__)

myDebuggingClass和myWarningClass都有一个重载的<<运算符,并对日志消息做一些有用的事情。

现在,我有一些用户将重载的基类称为“Widget”,我想将这些定义更改为更像:

#define DEBUG  myDebuggingClass(__FILE__, __FUNCTION__, __LINE__, this)
#define WARNING myWarningClass(__FILE__, __FUNCTION__, __LINE__, this)

这样当用户调用'DEBUG <<“Some Message”时; '我可以查看“this”参数是否为一个Widget进行dynamic_casts,如果是这样,我可以用这些信息做一些有用的事情,如果没有,那么我可以忽略它。 唯一的问题是我希望用户能够从非成员函数(例如main())发出DEBUG和WARNING消息。 但是,给定这个简单的宏,用户只会得到一个编译错误,因为“this”不会在类成员函数之外定义。

最简单的解决方案是只定义单独的WIDGET_DEBUG,WIDGET_WARNING,PLAIN_DEBUG和PLAIN_WARNING宏,并记录与用户的差异,但如果有办法解决这个问题,那将是非常酷的。 有没有人看到做这种事情的任何伎俩?

声明一个全局Widget* const widget_this = NULL; 和一个受保护的成员变量widget_this在Widget类中,初始化为this ,并执行

#define DEBUG myDebuggingClass(__FILE__, __FUNCTION__, __LINE__, widget_this)

宏基本上是由预处理器完成的直接文本替换。 宏没有办法知道它被调用的上下文来进行你感兴趣的那种检测。

你怀疑,最好的解决方案可能是单独的宏。

我不认为你可以用宏来做到这一点。 你也许可以管理与SFINAE做到这一点,但使用SFINAE(至少直接)代码是1很难写,很难调试,而且几乎不可能对任何人,但专家阅读或理解。 如果你真的想这样做,我会试着看看你是否可以获得Boost enable_if (或其亲属)来处理至少部分脏工作。

1 ...至少在我见过的每一个案例中,我都很难想象它也不是。

受到solipist的启发,但在实现中稍微简单一些:

class Widget { 
  protected: 
  ::myDebuggingClass myDebuggingClass(char const* file, char const* function, int line) {
    return ::myDebuggingClass(file, function, line, this);
  }
  // ...

这消除了对阴影变量的需要; 它依赖于简单的类名查找规则。

您可以使用弱引用来检测变量或函数是否存在。 例如:detect int a exists:

int 属性 ((弱)); 如果(a)存在,否则不存在

我能想到的唯一方法就是定义一个全局变量:

Widget * this = NULL;

如果这甚至编译(我有疑问,但没有编译器来测试它),成员函数将使用最近的范围变量(真正的his指针),其他一切将得到null。 每个人都很开心(可以这么说......)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM