是否有宏或规定要检查代码行是否在类内

Is there a macro or provision to check is the line of code is inside a class?

本文关键字:是否 代码 检查      更新时间:2023-10-16

我的代码中有一个 c 样式宏,用于打印日志。我想更改宏以打印指针。但是,代码的某些部分不是类的成员函数,或者有些是静态函数。所以,在我的宏中,我想检查当前代码行是否在成员函数内。 可能吗?

No.顾名思义,预处理器首先运行。将标记序列解释为类定义由编译器完成,编译器在预处理器之后运行。因此,预处理器不知道类、函数、变量或任何其他C++构造。

顺便说一句,在类中,您仍然有static也没有this指针的方法。

嗯,这并不完全符合您的需求,但将其集成到构建环境中可能是可行的。(编辑:我只是意识到静态成员函数失败;嗯。

我的想法是定义一个函数log()两次:一次在全局命名空间中;这是从freestandig函数中调用的名称解析的明显结果。另一个log()是基类的成员函数,所有要记录的类都必须从中继承。(这是一件坏事;对于一个庞大的现有代码库来说,这几乎不可行。继承、函数定义和调用可以依赖于预处理器定义,这样它们就不会对生产代码产生影响:

#include<cstdio>
// The following would go in a header which must be included by all source
// files which use one of the macros, i.e. which want to log errors.
#ifdef DEBUG
#   define INHERIT_LOG() : virtual protected logT
#   define LOG(s) log(s)
    /** ::log which will be called by free-standing functions */
    static void log(const char *err, const void *thisP = nullptr) 
    { 
        if(thisP) { fprintf(stderr, "this=%p: %sn", thisP, err); }
        else      { fprintf(stderr, "free func: %sn", err); }
    }
    /** A base class to inherit from when logging is required */
    class logT
    {   // this name "log" will be preferred over ::log 
        // from within all classes which inherit from logT.
        protected: void log(const char *const err){ ::log(err, this); }
    };
#else
//  define the macros to do nothing
#   define INHERIT_LOG()
#   define LOG(s)
#endif
////////////// end of log header ///////////////
/** Inherits from logT only when DEBUG is defined */                          
struct T INHERIT_LOG() { void f(); };
void T::f() { LOG("message from T::f"); }// if LOG is expanded to log, calls logT::log
void f()    { LOG("message from ::f"); } // if LOG is expanded to log, calls     ::log 
int main()
{
    T().f();
    f();
}

示例会话:

$ g++ -std=c++14 -Wall -o log log.cpp && ./log
$ g++ -DDEBUG -std=c++14 -Wall -o log log.cpp && ./log
this=0xffffcc00: message from T::f
free func: message from ::f
$

AFAIK 这并不容易实现。无法检查变量是否在预处理器中定义。

您可以引入一个新逻辑(例如在每个逻辑中插入一些内容)定义它类型的函数),但它可能更容易如果是否定义了this,则为案例提供两个宏。