C++11 __如果前面有范围,则VA_ARGS_uuu扩展失败

C++11 __如果前面有范围,则VA_ARGS_uuu扩展失败,c++11,visual-studio-2015,C++11,Visual Studio 2015,我想在宏中使用\uu VA\u ARGS\uu,如果(a==b)返回c,就相当于写入几行 在编译“小样本”时,它失败了 identifier "name2" is undefined (Line 18) C2065 'name3': undeclared identifier (Line 18) C2065 'name2': undeclared identifier (Line 18) 如果定义了使用枚举类和使用可变转换器 有点漫无边际 我发现有关Visual Studio早期版本无法扩展\

我想在宏中使用
\uu VA\u ARGS\uu
,如果(a==b)返回c,就相当于写入几行

在编译“小样本”时,它失败了

identifier "name2" is undefined (Line 18)
C2065 'name3': undeclared identifier (Line 18)
C2065 'name2': undeclared identifier (Line 18)
如果定义了
使用枚举类
使用可变转换器

有点漫无边际 我发现有关Visual Studio早期版本无法扩展
\uu VA\u ARGS\uuu
的信息,但由于代码可以使用
枚举
而不是
枚举类
正常工作,我想Visual Studio 2015至少解决了以前的一些问题。在实际的应用程序中,我会多次使用类似的宏,这样可以节省大量的行数,防止忘记为其添加代码 稍后添加的枚举值(添加到
NAME\u列表中即可)

小样本 这会导致上述错误。注释掉定义
USE_ENUM\u CLASS
USE_VARIADIC\u CONVERTER
的任何一行,它将编译

#define NAME_LIST name1,name2,name3
#define USE_ENUM_CLASS
#define USE_VARIADIC_CONVERTER

#ifdef USE_ENUM_CLASS
enum class e
#else
enum e
#endif
{
    name1, name2, name3
};

e int_to_e(int const i)
{
#ifdef USE_VARIADIC_CONVERTER
#define POPULATE_INT_TO_E(...) if(i==static_cast<int>(e::__VA_ARGS__)) return e::__VA_ARGS__;
    POPULATE_INT_TO_E(NAME_LIST);
#else
#define POPULATE_INT_TO_E(x) if(i==static_cast<int>(e::x)) return e::x
    POPULATE_INT_TO_E(name1);
    POPULATE_INT_TO_E(name2);
    POPULATE_INT_TO_E(name3);
#endif
    throw - 1;
}

void main(void)
{
}

问题:
如何重写/扩展宏以避免这些错误?

之所以失败,是因为
\uu VA\u ARGS\uuuu
没有按照您的想法执行。我怀疑您期望的是类似于可变模板的行为(在扩展包时复制整个表达式),但实际上它只是将所有参数转储到位

因此,当扩展
填充到(名称列表)
(可变版本)时,您会得到:

if(i==static_cast<int>(e::name1, name2, name3))
    return e::name1, name2, name3;
然后,您可以定义
X
,展开
NAME\u列表
,您将拥有所追求的行为:

#define X(name_) \
    if(i==static_cast<int>(e::name_)) return e::name_;

NAME_LIST

#undef X
定义X(名称)\ 如果(i==static_cast(e::name_u))返回e::name_u; 名单 #未定义X
。。。扩展到:

if(i==static_cast<int>(e::name1)) return e::name1;
if(i==static_cast<int>(e::name2)) return e::name2;
if(i==static_cast<int>(e::name3)) return e::name3;
if(i==static_cast(e::name1))返回e::name1;
如果(i==static_cast(e::name2))返回e::name2;
如果(i==static_cast(e::name3))返回e::name3;

另一个答案是迭代VA_ARGS

#define NAME_LIST e::name1,e::name2,e::name3
#define USE_ENUM_CLASS
#define USE_VARIADIC_CONVERTER

#ifdef USE_ENUM_CLASS
enum class e
#else
enum e
#endif
{
    name1, name2, name3
};

e int_to_e(int const i)
{
#ifdef USE_VARIADIC_CONVERTER
#define POPULATE_INT_TO_E(...) \
    e _arr[] = {__VA_ARGS__}; \
    int _i; \
    for (_i = 0; _i < sizeof(_arr)/sizeof(_arr[0]); _i++) { \
      if(i==static_cast<int>(_arr[_i])) return _arr[_i]; \
    }
    POPULATE_INT_TO_E(NAME_LIST);
#else
#define POPULATE_INT_TO_E(x) if(i==static_cast<int>(e::x)) return e::x
    POPULATE_INT_TO_E(name1);
    POPULATE_INT_TO_E(name2);
    POPULATE_INT_TO_E(name3);
#endif
    throw - 1;
}

int main(void)
{
}
#定义名称#列表e::name1、e::name2、e::name3
#定义使用枚举类
#定义使用可变转换器
#ifdef使用枚举类
枚举类e
#否则
枚举e
#恩迪夫
{
名字1,名字2,名字3
};
e int_至_e(int const i)
{
#ifdef使用可变转换器
#定义填充到(…)\
e_arr[]={{uu VA_ARGS}\
int_i\
对于(_i=0;_i
但必须将名称列表定义为
e::name1、e::name2、e::name3

#define NAME_LIST \
    X(name1) \
    X(name2) \
    X(name3)
#define X(name_) \
    if(i==static_cast<int>(e::name_)) return e::name_;

NAME_LIST

#undef X
if(i==static_cast<int>(e::name1)) return e::name1;
if(i==static_cast<int>(e::name2)) return e::name2;
if(i==static_cast<int>(e::name3)) return e::name3;
#define NAME_LIST e::name1,e::name2,e::name3
#define USE_ENUM_CLASS
#define USE_VARIADIC_CONVERTER

#ifdef USE_ENUM_CLASS
enum class e
#else
enum e
#endif
{
    name1, name2, name3
};

e int_to_e(int const i)
{
#ifdef USE_VARIADIC_CONVERTER
#define POPULATE_INT_TO_E(...) \
    e _arr[] = {__VA_ARGS__}; \
    int _i; \
    for (_i = 0; _i < sizeof(_arr)/sizeof(_arr[0]); _i++) { \
      if(i==static_cast<int>(_arr[_i])) return _arr[_i]; \
    }
    POPULATE_INT_TO_E(NAME_LIST);
#else
#define POPULATE_INT_TO_E(x) if(i==static_cast<int>(e::x)) return e::x
    POPULATE_INT_TO_E(name1);
    POPULATE_INT_TO_E(name2);
    POPULATE_INT_TO_E(name3);
#endif
    throw - 1;
}

int main(void)
{
}