首页 > 解决方案 > 即使使用 ##__VA_ARGS__ 也无法编译零参数的可变参数宏

问题描述

如果我尝试编译以下代码:

template <typename... TArgs>
void Dummy(const TArgs &...args)
{
}

#define DUMMY(...) Dummy("Hello", ##__VA_ARGS__)

int main()
{
    DUMMY();
}

我收到以下编译错误:

g++ -std=c++17 -O3 -Wall main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:6:48: error: expected primary-expression before ')' token
    6 | #define DUMMY(...) Dummy("Hello", ##__VA_ARGS__)
      |                                                ^
main.cpp:10:5: note: in expansion of macro 'DUMMY'
   10 |     DUMMY();
      |     ^~~~~

https://coliru.stacked-crooked.com/a/c9217ba86e7d24bd

当我添加至少一个参数时,代码编译得很好:

template <typename... TArgs>
void Dummy(const TArgs &...args)
{
}

#define DUMMY(dummy, ...) Dummy(dummy, ##__VA_ARGS__)

int main()
{
    DUMMY(); // This is strange. Why does this compile?
    DUMMY(1);
    DUMMY(1, 2);
    DUMMY(1, 2, 3);
}

https://coliru.stacked-crooked.com/a/e30e14810d70f482

但我不确定它是否正确,因为DUMMY至少需要一个参数,但我传递了零。

标签: c++c-preprocessorvariadic-macros

解决方案


使用零参数时,标准__VA_ARGS__不会删除尾随。,##__VA_ARGS__删除额外,的是一个 GCC 扩展。

此 GCC 扩展不起作用,因为您使用的是标准兼容模式-std=c++17,而不是-std=gnu++17.


推荐阅读