在下面的示例代码中,我想使用带有变量参数的MACRO_EXPANSION
和{...}
来构造EnumTypes
对象的列表。但是,我无法使这个想法起作用。 (PS。代码结构可能看起来不太好,但是我需要它:))
#include <iostream>
#include <utility>
#include <initializer_list>
enum class EnumOneTypes {
One0,
One1
};
enum class EnumTwoTypes {
Two0,
Two1
};
struct EnumTypes {
EnumOneTypes one;
EnumTwoTypes two;
};
void do_something(std::initializer_list<EnumTypes> il) {
std::cout << "Do something" << std::endl;
}
// Need this struct to forward arguments
struct Register {
template <typename... TArgs>
Register(TArgs&&... args) {
do_something(std::forward<TArgs>(args)...);
//also do other things after do_something, omit here
// ...
}
};
// Use this macro to define global static objects
#define MACRO_EXPANSION(name, ...) \
static struct Register name(__VA_ARGS__)
MACRO_EXPANSION(
register_two,
{EnumOneTypes::One0, EnumTwoTypes::Two0},
{EnumOneTypes::One1, EnumTwoTypes::Two1}
);
MACRO_EXPANSION(
register_three,
{EnumOneTypes::One0, EnumTwoTypes::Two0},
{EnumOneTypes::One1, EnumTwoTypes::Two1},
{EnumOneTypes::One0, EnumTwoTypes::Two1}
);
int main() {
std::cout << "Test the usage of this macro" << std::endl;
return 0;
}
答案 0 :(得分:2)
std::initializer_list
。因此,让我们用方括号将可变参数括起来。struct Register {
template <typename... TArgs>
Register(TArgs&&... args) {
do_something({std::forward<TArgs>(args)...}); // Make params to be initializer List
//also do other things after do_something, omit here
// ...
}
};
Register
构造函数是模板化的,因此似乎编译器无法推断{EnumOneTypes::One0, EnumTwoTypes::Two0}
属于哪种类型。因此,让我们将其类型指定为:MACRO_EXPANSION(
register_two,
EnumTypes{EnumOneTypes::One0, EnumTwoTypes::Two0},
EnumTypes{EnumOneTypes::One1, EnumTwoTypes::Two1}
);
应用这两个方法之后,它会成功编译并运行输出:
Do something
Do something
Test the usage of this macro
我在godbolt中进行了测试。