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)
{
}