c++ - 使用参数专门化宏

标签 c++ variadic-macros

假设我有以下宏:

#define LOG(L, ...) func(L, __VA_ARGS__);

其中L可以是INFO, WARN, FATAL之一

现在,我想为FATAL定义不同的名称。
#define LOG(FATAL, ...) {func(FATAL, __VA_ARGS__); exit(-1);}

如何做到这一点?

编辑:
作为上述的后续措施,还有更好的方法吗?即例如避免使用宏。

最佳答案

宏在C++中通常是一个错误的选择–基本上是因为它们与 namespace 无关,并且可能在意外发生时生效。

就是说–有关如何解决OP问题的示例,例如使用token pasting:

#include <iostream>

#define LOG(LEVEL, ...) LOG_##LEVEL(__VA_ARGS__)

#define LOG_INFO(...) log(Info, __VA_ARGS__)
#define LOG_WARN(...) log(Warn, __VA_ARGS__)
#define LOG_FATAL(...) do { log(Error, __VA_ARGS__); std::cerr << "Program aborted!\n"; } while (false)

enum Level { Info, Warn, Error };

void log(Level level, const char *text)
{
  static const char *levelText[] = { "INFO", "WARNING", "ERROR" };
  std::cerr << levelText[level] << ": " << text << '\n';
}

int main()
{
  LOG(INFO, "Everything fine. :-)");
  LOG(WARN, "Not so fine anymore. :-|");
  LOG(FATAL, "Things became worst. :-(");
}

输出:

INFO: Everything fine. :-)
WARNING: Not so fine anymore. :-|
ERROR: Things became worst. :-(
Program aborted!

Live Demo on coliru

后续问题的另一个示例-使用可变参数模板而不是宏:
#include <iostream>

enum Level { Info, Warn, Error, Fatal };

template <typename ...ARGS>
void log(Level level, ARGS&& ... args)
{
  static const char *levelText[] = { "INFO", "WARNING", "ERROR", "FATAL" };
  std::cerr << levelText[level] << ": ";
  (std::cerr << ... << args);
  std::cerr << '\n';
  if (level == Fatal) std::cerr << "Program aborted!";
}

int main()
{
  log(Info, "Everything fine.", ' ', ":-)");
  log(Warn, "Not so fine anymore.", ' ', ":-|");
  log(Error, "Things became bad.", ' ', ":-(");
  log(Fatal, "Things became worst.", ' ', "XXX");
}

输出:

INFO: Everything fine. :-)
WARNING: Not so fine anymore. :-|
ERROR: Things became bad. :-(
FATAL: Things became worst. XXX
Program aborted!

Live Demo on coliru

我必须承认我需要一些有关参数解压缩的帮助-在此处找到:
SO: What is the easiest way to print a variadic parameter pack using std::ostream?

关于c++ - 使用参数专门化宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61114459/

相关文章:

c++ - 解码电子邮件的有趣 ISO 编码

c++ - 为什么值放在 fortran 函数的数组中而不是在调用 c++ 函数中?

c++ - 编译C++程序导致 "Fatal Error LNK1104"

c++ - Visual Studio 2010 如何为 C++ 项目托管 MSBuild?

c - 替换嵌套 for 循环的宏

c++ - 如何正确扩展宏?

带有键的 C++11 映射定义了一个值范围

c++ - 使用可变函数/宏简化工作

c - 函数的参数如何成为类型? (类似于 va_arg 的第二个参数)

c++ - 字符串化 __VA_ARGS__ (C++ 可变参数宏)