[英]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.