【问题标题】:variadic macro - optional initializer expression可变参数宏 - 可选的初始化表达式
【发布时间】:2017-03-20 10:26:06
【问题描述】:

我想要一个macro,它声明一个具有给定名称和可选初始化表达式的int

我尝试使用this answer on Stack Overflow,但没有成功。

这是我尝试过的:

#define macro(...) int FIRST(__VA_ARGS__)(REST(__VA_ARGS__))

这样使用没有问题:

macro(foo);

但是当给定初始化器时会出现错误:

macro(foo, 42);

当没有参数时,仅使用 __VA_ARGS__ 的替代方法会在 GCC 中发出来自 -pedantic 的警告。

我该如何解决这个问题?

当没有初始化表达式时是否也可以避免 () 大括号 - 意味着没有零初始化但默认值?

请注意,我的实际用例不仅适用于 int,而且适用于任何类型,并且不能选择使用像 boost 这样的第三方。

【问题讨论】:

  • 很少有人推荐使用宏,因为它们往往会混淆代码。您能否详细说明您尝试使用此解决方案解决的原始问题? 为什么你用这种方式使用宏?也许还有其他方法可以解决您的解决方案,不依赖于宏的方法?
  • 您可以通过实际编写 C++ 代码来解决此问题,而不是尝试使用这种粗鲁、过时的 C 语法,并使用模板;这是在 C++ 中执行此操作的正确方法。这是一个很宽泛的话题,不适合简短的回答;所以你需要做的就是打开你的 C++ 到讨论模板的章节,然后开始阅读。
  • C++ 不够强大,因此我需要借助宏来生成代码。成千上万的项目依赖于预处理器。我知道这不是一个令人愉快的问题要解决,但我只是寻求帮助 - 如果我不明白 - 没关系。
  • 为这个用例做一个宏有什么意义? int foo=42; 更明确。
  • 你怎么知道 C++“不够强大”? 我们怎么知道?你的问题是the XY problem 的一个例子,你告诉我们你想要修复的解决方案,但不要告诉我们解决方案应该解决什么问题。仅仅因为数以千计的项目以一种可能不好的方式使用宏并不意味着您必须这样做。

标签: c++ c++11 c-preprocessor variadic-macros


【解决方案1】:
#define macro(...) int FIRST(__VA_ARGS__){REST(__VA_ARGS__)}

您的主要问题是int foo(); 是一个函数声明。 int foo{}; 不是。

【讨论】:

  • 天哪,我完全忘记了令人烦恼的解析 - 感谢您指出!
【解决方案2】:

最后我得到了以下结果:link

我将__VA_ARGS__ 转发到可变参数模板,因为我的问题与我在此处描述的不完全一致(如 cmets 中所建议的那样) - 但不提供初始化程序时的问题仍然存在 - 所以我将标题中的警告静音对于带有#pragma GCC system_header 的GCC 和对于Clang,我使用_Pragma() 作为-Wgnu-zero-variadic-macro-arguments。 MSVC 不是问题。

正如@MSalters 在他的回答中指出的那样,我也成为了最令人烦恼的解析的受害者。

【讨论】:

    猜你喜欢
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 2016-02-12
    • 1970-01-01
    • 2021-09-14
    • 2023-01-02
    相关资源
    最近更新 更多