是否可以在c ++中的命名空间中放置一个宏?

Tib*_*ibi 17 c++ macros namespaces

我的应用程序使用比标准输出日志信息,这就是为什么我写我自己的另一个输出Log(),Error(),Panic()Assert()功能.为了很好地组织事情,我将所有调试内容放在Debug命名空间中.

对于该Assert()函数来说,提供源文件和行号更有意义,这只能使用__LINE____FILE__宏来实现.然而,总是必须指定这两个参数,这是非常不愉快,低效等等.

所以这就是我的代码的样子:

namespace Debug {
   void Assert (int condition, std::string message, std::string file, int line);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,是否可以在Debug命名空间中放置一个包含这两个参数的宏?像这样:

namespace Debug {
   void Assert_ (int condition, std::string message, std::string file, int line);
   #define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}

// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");

// Output: Assertion failed on line 10 in file test.cpp:
//           Some_condition should be true
Run Code Online (Sandbox Code Playgroud)

这是有效的c ++吗?如果没有,有没有办法使这项工作?

Sin*_*all 29

#define是一个预处理器指令.宏被替换之前二话不说从删除注释(这意味着,在编译之前).因此,在宏被替换时,编译器对您的命名空间一无所知.

正如其他人所说,在你的情况下,它会没事的.但是,这就是你可以遇到的问题:

namespace A
{
 void Assert_ (int condition, std::string message, std::string file, int line)
 {
     std::cout << "A";
 }
   #define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)

}
namespace B
{
 void Assert_ (int condition)
 {
     std::cout << "B";
 }
   #define Assert(a,b) Assert_(a)

}

int main(int argc, char *argv[])
{
    A::Assert(0,"asdasd");
    B::Assert(0,"asdasd");
}
Run Code Online (Sandbox Code Playgroud)

因此,虽然看起来定义是"在名称空间中",但它们不是,并且最后#define将始终使用,在这种情况下将导致编译时错误,因为main中的代码将替换为:

A::Assert(0);
B::Assert(0);
Run Code Online (Sandbox Code Playgroud)

代替

A::Assert(0,"asdasd", _FILE_, _LINE_);
B::Assert(0);
Run Code Online (Sandbox Code Playgroud)

  • @Tibi - 方式不是使用`宏`.使用命名空间中定义的常量或内联函数. (3认同)