如何在 C++ 预处理中以不同方式处理元组和单个标记?
How to handle tuples and single tokens differently in C++ preprocessing?
我想定义一个INITIALIZE(...)
实现以下
struct MyStruct {
std::string a;
bool b;
char c;
double d;
INITIALIZE(a, (b, true), (c, '$'), d);
};
扩展到
struct MyStruct {
std::string a;
bool b;
char c;
double d;
void init() {
a = get_value<std::string>(); // use return value of get_value function
b = true; // use init value from the macro
c = '$'; // use init value from the macro
d = get_value<double>(); // use return value of get_value function
}
};
这些可以借助 Boost_PP
宏实现吗?
T get_value<T>()
在库中定义。
这几乎是可行的,您需要一对额外的括号围绕默认初始化的事物。
#define INIT_1(x) x = get_value<decltype(x)>();
#define INIT_2(x, y) x = y;
#define INIT_ONE(...) BOOST_PP_CAT(INIT_, \
BOOST_PP_VARIADIC_SIZE(__VA_ARGS__))(__VA_ARGS__)
#define INIT_ONE_X(r, data, elem) INIT_ONE elem
#define INITIALIZE(...) void init () { BOOST_PP_SEQ_FOR_EACH( \
INIT_ONE_X, x, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) }
现在 INITIALIZE((a), (b, 'a'), (c))
扩展到
void init () { a = get_value<decltype(a)>(); b = 'a'; c = get_value<decltype(c)>(); }
编辑:正如@Quentin 所建议的,您可以通过使用类似于this 的宏来删除额外的括号。必要的更改是
#define INIT_ONE_XX(elem) INIT_ONE elem
#define INIT_ONE_X(r, data, elem) INIT_ONE_XX(ENSURE_PARENS(elem))
#define ENSURE_PARENS(...) \
BOOST_PP_REMOVE_PARENS( \
BOOST_PP_IF( \
BOOST_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
(__VA_ARGS__), \
((__VA_ARGS__)) \
) \
)
那么INITIALIZE(a, (b, 'a'), c)
也可以。
编辑:更好、更少阻碍的语法是可能的,这取决于我们生成的具体 C++ 构造。请参阅 http://aantron.github.io/better-enums/ 以获取灵感。
我想定义一个INITIALIZE(...)
实现以下
struct MyStruct {
std::string a;
bool b;
char c;
double d;
INITIALIZE(a, (b, true), (c, '$'), d);
};
扩展到
struct MyStruct {
std::string a;
bool b;
char c;
double d;
void init() {
a = get_value<std::string>(); // use return value of get_value function
b = true; // use init value from the macro
c = '$'; // use init value from the macro
d = get_value<double>(); // use return value of get_value function
}
};
这些可以借助 Boost_PP
宏实现吗?
T get_value<T>()
在库中定义。
这几乎是可行的,您需要一对额外的括号围绕默认初始化的事物。
#define INIT_1(x) x = get_value<decltype(x)>();
#define INIT_2(x, y) x = y;
#define INIT_ONE(...) BOOST_PP_CAT(INIT_, \
BOOST_PP_VARIADIC_SIZE(__VA_ARGS__))(__VA_ARGS__)
#define INIT_ONE_X(r, data, elem) INIT_ONE elem
#define INITIALIZE(...) void init () { BOOST_PP_SEQ_FOR_EACH( \
INIT_ONE_X, x, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) }
现在 INITIALIZE((a), (b, 'a'), (c))
扩展到
void init () { a = get_value<decltype(a)>(); b = 'a'; c = get_value<decltype(c)>(); }
编辑:正如@Quentin 所建议的,您可以通过使用类似于this 的宏来删除额外的括号。必要的更改是
#define INIT_ONE_XX(elem) INIT_ONE elem
#define INIT_ONE_X(r, data, elem) INIT_ONE_XX(ENSURE_PARENS(elem))
#define ENSURE_PARENS(...) \
BOOST_PP_REMOVE_PARENS( \
BOOST_PP_IF( \
BOOST_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
(__VA_ARGS__), \
((__VA_ARGS__)) \
) \
)
那么INITIALIZE(a, (b, 'a'), c)
也可以。
编辑:更好、更少阻碍的语法是可能的,这取决于我们生成的具体 C++ 构造。请参阅 http://aantron.github.io/better-enums/ 以获取灵感。