gpt4 book ai didi

c++ - 重载C预处理程序宏-基于调用语法的区分

转载 作者:行者123 更新时间:2023-12-02 10:11:37 25 4
gpt4 key购买 nike

我目前正在使用cpp记录器,该记录器旨在在每个打印的消息之前显示__FILE____LINE__。就我而言,我们主要使用两种打印方法:printf样式和std::cout样式。目前,每种样式都有一个宏:

#define HATFormatFatal(...)    HATLogger::logFormat(HATLogger::LogLevel::FATAL, __FILE__, __LINE__, __VA_ARGS__)
#define HATFormatError(...) HATLogger::logFormat(HATLogger::LogLevel::ERROR, __FILE__, __LINE__, __VA_ARGS__)
等...以及:
#define HATStreamFatal   HATLogger::logStream(HATLogger::LogLevel::FATAL, __FILE__, __LINE__)
#define HATStreamError HATLogger::logStream(HATLogger::LogLevel::ERROR, __FILE__, __LINE__)
这些宏可以在下面调用:
HATFormatError("This is an %s message", "ERROR");
HATStreamError << "This is an " << "ERROR" << " message" << std::endl;
我想用相同的名字来称呼他们:HATLogError。正确的宏将在寻找括号时在编译时确定。 到目前为止,我已经看到一些示例,这些示例显示了如何通过参数的数量来区分宏,但是没有什么可以处理“非括号”情况。
有谁知道如何实现这一目标?

最佳答案

最简单的方法是根本不重载宏,而是让宏返回一个同时重载了operator<<operator()的对象。像这样:

class error_logger {
public:
error_logger(
HATLogger::LogLevel level,
char const * file,
char const * line
) : level{level}, file{file}, line{line} { }

template <typename... T>
void operator()(T && ... args) {
HATLogger::logFormat(level, file, line, std::forward<T>(args)...);
}

template <typename T>
HATLogger::logStream operator<<(T && arg) {
HATLogger::logStream stream{level, file, line};

stream << std::forward<T>(arg);

return stream;
}

private:
HATLogger::LogLevel level;
char const * file;
char const * line;
};
(此示例假定 HATLogger::logStream可以移动。可能需要根据您的代码的详细信息对该示例实现进行调整,但是我在此处演示的是基本方法。)
现在您可以执行以下操作:
#define HATFormatFatal  (error_logger{HATLogger::LogLevel::FATAL, __FILE__, __LINE__})
然后可以同时使用 HATFormatFatal << ...HATFormatFatal(...)

关于c++ - 重载C预处理程序宏-基于调用语法的区分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63330463/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com