基于宏函数参数的C++宏函数扩展
C++ macro function expansion based on the macro function arguments
我使用的一些系统没有我正在使用的日志库,这对于生产运行中经过良好测试的代码来说是可以的——日志库主要用于调试和测试。在我的主要开发机器上,以及在我经常运行实验的几台服务器上,都存在日志库。但偶尔我需要将实验分散到另一台具有更多节点和核心的服务器上,但没有日志库。
例如,该库(Google glog)提供以下宏函数:
LOG(INFO) << "Insert my message here.";
LOG(FATAL) << "Insert another message here.";
因此,我所做的定义如下:
#ifdef NOLOGGING
#define MYLOG(i,m) std::cerr << #i << ": " << m << "n";
#else
#define MYLOG(i,m) LOG(i) << m ;
#endif
使用这些定义,我现在可以编写这样的语句:
MYLOG(INFO, "My info message");
MYLOG(FATAL,"My fatal message");
如果使用标志-DNOLOGGING
编译,则最后两条语句将扩展为:
std::cerr << "INFO" << ": " << "My info message" << "n";
std::cerr << "FATAL" << ": " << "My fatal message" << "n";
其中,如果-DNOLOGGING
标志是而不是编译中使用的,则它们将扩展为:
LOG(INFO) << "My info message";
LOG(FATAL) << "My fatal message";
我上面描述的解决方案是令人满意的,但并不理想。
理想情况下,当我无法访问日志库时,像MYLOG(FATAL,"foo")
这样的语句会扩展到打印到std::cerr
的语句然而,像MYLOG(INFO,"bar")
这样的语句将扩展为零。换句话说,当我不能使用日志库时,我希望像MYLOG(INFO,"bar")
这样的语句被忽略。这个想法是,当我使用没有日志库的服务器时,我不太关心INFO
严重性的日志消息,但我仍然希望看到FATAL
严重性的消息。
如果可能,我如何仅使用预处理器指令来完成此操作
我认为你不能只使用预处理指令来完成这项工作,因为预处理程序并没有真正为你提供必要的机制来指导基于宏参数的宏扩展。
也就是说,你可以犯一些稍微丑陋的黑客行为,这些行为会奏效。考虑以下代码:
#include <iostream>
#define MYLOG_ERR 1
#define MYLOG_INFO 0
#define P(a,b) a##b
#define MYLOG(x,y) do { if (P(MYLOG_,x)) { std::cerr << y << std::endl; } } while (0)
int main(void)
{
MYLOG(ERR, "err");
MYLOG(INFO, "info");
}
这种方法依赖于编译器的优化器来识别一些常见的习惯用法,如do { ... } while (0)
和if (0)
/if (1)
,以优化编译时的已知条件。但是,我认为它会给你想要的。
相关文章:
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 扩展类中的可选 vir 函数,测试它在运行时是否存在
- 内联扩展编译为函数调用 [C++]
- 在 *.cpp 文件中实现的 c++ 函数/方法永远不会内联扩展吗?
- 可变参数函数参数包扩展
- 从函数为 std::vector 创建自定义扩展
- 宏函数未按预期扩展
- 为什么用C++编写的 phpcpp 扩展函数比用 PHP 编写的函数慢
- 模板包扩展以将函数应用于连续的参数对
- 模板 使用数据数组调用函数时扩展参数包
- 扩展包含静态函数的类
- 是否可以在可变参数模板函数中扩展非可变参数?
- 折叠表达式、参数包扩展、类成员函数中的递归
- 将RCPP函数扩展到任何类型的输入向量
- 为什么我不能在 c++ 类中声明一个空构造函数,该构造函数从一个具有私有构造函数的构造函数扩展而来
- 我们可以用自定义函数扩展现有的类吗?(无继承)
- 基于宏函数参数的C++宏函数扩展
- 将c++数学函数扩展到非基本类型
- 我应该为比较函数扩展std::less吗?
- 虚函数 - 扩展抽象类 c++