首页 > 解决方案 > MSVC 预处理器错误 - 在参数计数上重载 C/C++ 宏

问题描述

我正在尝试编写一个重载的宏来格式化StringMap条目,并且当有多个参数时无法让预处理器识别。我已经查看了几乎所有类似的问题,并尝试了 5 种以上的实现,但都没有奏效。比如这个问题

我的实现与接受的答案相同,如下所示:

#define STRING_MAP_ENTRY_1(a) \
  { a, #a }
#define STRING_MAP_ENTRY_2(a, b) \
  { a, b }

#define STRING_MAP_ENTRY( ... ) VA_SELECT( STRING_MAP_ENTRY, __VA_ARGS__ )
#define CAT( A, B ) A ## B
#define SELECT( NAME, NUM ) CAT( NAME ## _, NUM )

#define GET_COUNT( _1, _2, _3, _4, _5, _6, COUNT, ... ) COUNT
#define VA_SIZE( ... ) GET_COUNT( __VA_ARGS__, 6, 5, 4, 3, 2, 1 )

#define VA_SELECT( NAME, ... ) SELECT( NAME, VA_SIZE(__VA_ARGS__) )(__VA_ARGS__)

这适用于单个参数调用,enum strings如下所示,但manual_strings我收到警告warning C4002: too many arguments for function-like macro invocation 'STRING_MAP_ENTRY_1'。这告诉我它不能正常工作,因为它没有调用_2版本。

static StringMap<uint8> const enum_strings = {
    STRING_MAP_ENTRY(ENUM_VALUE_1),
    STRING_MAP_ENTRY(ENUM_VALUE_2)};

static StringMap<uint8> const manual_strings = {
    STRING_MAP_ENTRY(0, "ENTRY_0"),
    STRING_MAP_ENTRY(1, "ENTRY_1")};

尝试我在类似问题中看到的所有其他实现时,我都会收到同样的警告。知道为什么它不起作用吗?我在这里和那里看到了很多关于编译器版本的注释。这可能是原因吗?该项目是使用 VS 2017 中的默认 MSVC 编译器编译的。我包含了 C 标签,因为尽管这是在 C++ 中,但宏定义都是有效的 C。

标签: c++visual-c++macrospreprocessorvariadic-macros

解决方案


推荐阅读