C++ 11中的空宏参数是否合法?

Sup*_*ric 25 c++ macros c++11

我有时会故意省略宏观论点.例如,对于类似函数的宏

#define MY_MACRO(A, B, C)  ...
Run Code Online (Sandbox Code Playgroud)

我可以称之为:

MY_MACRO(, bar, baz)
Run Code Online (Sandbox Code Playgroud)

技术上还有3个论点; 只是第一个是"空的".这个问题不是关于可变参数的宏.

当我这样做时,我在使用-ansi(又名-std=c++98)编译时会收到来自g ++的警告,但是当我使用时却没有-std=c++0x.这是否意味着新的宏args在新的C++标准中是合法的?

这是我的全部问题,但期待"你为什么要这样做?" 回复,这是一个例子.我喜欢保持.h文件不被函数体整理,但是在.h文件之外实现简单的访问器是很乏味的.因此我写了以下宏:

#define IMPLEMENT_ACCESSORS(TEMPLATE_DECL, RETURN_TYPE, CLASS, FUNCTION, MEMBER) \
  TEMPLATE_DECL                                                         \
  inline RETURN_TYPE* CLASS::Mutable##FUNCTION() {                      \
    return &MEMBER;                                                     \
  }                                                                     \
                                                                        \
  TEMPLATE_DECL                                                         \
  inline const RETURN_TYPE& CLASS::FUNCTION() const {                   \
    return MEMBER;                                                      \
  }
Run Code Online (Sandbox Code Playgroud)

这就是我如何将它用于包含被int调用的类模板int_:

IMPLEMENT_ACCESSORS(template<typename T>, int, MyTemplate<T>, Int, int_)
Run Code Online (Sandbox Code Playgroud)

对于非模板类,我不需要template<typename T>,所以我省略了这个宏参数:

IMPLEMENT_ACCESORS(, int, MyClass, Int, int_)
Run Code Online (Sandbox Code Playgroud)

Ise*_*ria 14

如果我理解正确,从C99和C++ 0x(11)开始就允许空的宏参数.
C99 6.10.3/4说:

...参数的数量(包括那些由没有预处理令牌组成的参数)应该等于参数的数量......

和C++ N3290 16.3/4有相同的说法,而C++ 03 16.3/10提到:

...任何参数都不包含预处理令牌,行为未定义.

我认为空参数属于上面没有预处理标记的表示参数.
另外,6.10.3 in the Internationalation Programming Languages C rev.5.10说:

C99的一个新功能:类似函数的宏调用现在也可能有空参数,也就是说,参数可能不包含预处理标记.


MSa*_*ers 8

是.相关位是16.3/11

由最外部匹配括号限定的预处理标记序列形成类似函数的宏的参数列表.列表中的各个参数由逗号预处理标记分​​隔.

不要求单个参数恰好对应于一个标记.实际上,以下部分清楚地表明每个参数可以有多个令牌:

在被替换之前,每个参数的预处理标记都被完全宏替换,好像它们形成了预处理文件的其余部分一样

在您的情况下,一个参数恰好对应于零令牌.这不会引起任何矛盾.

[编辑] N1566改变了这一点,使C++ 11符合C99.

  • @eudoxos GCC选择在C89和/或C++ 98中处理一堆未定义的行为,但由C99定义,因为它们具有C99语义,无论C99支持是否明确打开.(在C99之前,其中许多都是"未定义但所有实现都是这样做的",这仅仅是编纂实践.) (2认同)

Mar*_*ork 5

当我这样做时,我通常会用评论代替论点。

放置一个将扩展为空字符串的宏。

#define NOARG
...
MY_MACRO(/*Ignore this Param*/ NOARG, bar, baz)
Run Code Online (Sandbox Code Playgroud)

附注。无论是否带有 -std=c++98 标志,我都没有收到 g++ 警告。

  • g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
  • g++ (Apple Inc. build 5666) 4.2.1

  • 那其实是一样的。根据 2.2 翻译阶段,注释在步骤 3 中替换为一个空格,宏在步骤 4 中替换。 (8认同)
  • 由于 MSalters 解释的原因,使用您的技巧,警告仍然存在(使用了 `clang -pedantic -std=c++98`)。避免警告的更好方法是使用扩展为空的虚拟宏,例如`#define NOARG` 然后你可以使用`MY_MACRO(NOARG, bar, baz)`。 (2认同)