[英]Statically iterate over all members of a C++ struct
Is there a way to statically iterate over all members of a C++ struct?有没有办法静态迭代 C++ 结构的所有成员?
Say if we have many predefined structs which look like:假设我们有许多预定义的结构,它们看起来像:
struct Foo {
int field1;
double field2;
char field3;
...
int field9;
};
struct Bar {
double field14;
char field15;
int field16;
bool field17;
...
double field23;
};
And we want to have a template function我们想要一个模板函数
template<typename T>
void Iterate(T object);
so that Iterate
can run a template function Add
over all the members of type T
.以便
Iterate
可以对T
类型的所有成员运行模板函数Add
。 For example, Iterate<Foo>
and Iterate<Bar>
would become例如,
Iterate<Foo>
和Iterate<Bar>
将变成
void Iterate<Foo>(Foo object) {
Add<int>(object.field1);
Add<double>(object.field2);
Add<char>(object.field3);
...
Add<int>(object.field9);
}
void Iterate<Bar>(Bar object) {
Add<double>(object.field14);
Add<char>(object.field15);
Add<int>(object.field16);
Add<bool>(object.field17);
...
Add<double>(object.field23);
}
This can be done by writing another program that parses the struct
definition and generate a cpp
file, but that would be too cumbersome and requires additional compiling and execution.这可以通过编写另一个程序来解析
struct
定义并生成cpp
文件来完成,但这会太麻烦并且需要额外的编译和执行。
Edit: The struct may have many fields, and they are predefined, so it can't be changed into other types.编辑:结构体可能有很多字段,并且它们是预定义的,因此不能更改为其他类型。 Also this is at compile-time, so it has less to do with "reflection", which is performed at run-time, and more to do with "template programming" or "metaprogramming".
这也是在编译时,所以它与在运行时执行的“反射”关系不大,而更多地与“模板编程”或“元编程”有关。 We have
<type_traits>
for type inspection at compile-time, but that does not seem to be enough.我们有
<type_traits>
用于编译时的类型检查,但这似乎还不够。
There is no clear standard way to do such thing, but you can look at non-standard way.没有明确的标准方法来做这样的事情,但你可以看看非标准的方法。 For example you can use
boost::fusion
.例如,您可以使用
boost::fusion
。
BOOST_FUSION_ADAPT_STRUCT(
Foo,
(int, field1)
(double, field2)
(char, field3)
);
adapt struct After that, you can use objects of type Foo
as fusion-sequence, which can be iterated by member. 适配 struct之后,就可以使用
Foo
类型的对象作为 fusion-sequence ,可以通过 member 进行迭代。 small live example活生生的小例子
I don't see any way to do this with a normal struct without retaining compile time information for the mapping of indices to types - at which point you create another std::tuple class.在不保留索引到类型映射的编译时信息的情况下,我看不出有任何方法可以使用普通结构执行此操作-此时您可以创建另一个 std::tuple 类。 Let's give this a try:
让我们试一试:
#include <iostream>
#include <tuple>
#include <typeinfo>
template <size_t Cur, size_t Last, class TupleType, template <typename> class Func>
struct Iterate_Helper
{
void operator()(TupleType& tuple)
{
typedef typename std::tuple_element<Cur, TupleType>::type elem_type;
Func<elem_type>()(std::get<Cur>(tuple));
Iterate_Helper<Cur+1, Last, TupleType, Func>()(tuple);
}
};
template <size_t Cur, class TupleType, template <typename> class Func>
struct Iterate_Helper<Cur, Cur, TupleType, Func>
{
void operator()(TupleType& tuple)
{
typedef typename std::tuple_element<Cur, TupleType>::type elem_type;
Func<elem_type>()(std::get<Cur>(tuple));
}
};
template <template <typename> class Func, class TupleType>
void iterate(TupleType& tuple)
{
Iterate_Helper<0, std::tuple_size<TupleType>::value-1, TupleType, Func>()(tuple);
}
template <typename T>
struct Add1
{
void operator()(T& t)
{
t += 1;
}
};
template <typename T>
struct Print
{
void operator()(T& t)
{
std::cout << (int)t << std::endl;
}
};
int main() {
typedef std::tuple<int, double, char, /* ... */ int> Foo;
Foo test(1, 2.0, 3, 4);
iterate<Add1>(test);
iterate<Print>(test);
return 0;
}
This is on top of my head but I hope it can give you some insight.这是在我的头顶上,但我希望它可以给你一些见解。
Yes this is well supported with Boost.Fusion and the extension mechanism.是的,Boost.Fusion 和扩展机制很好地支持了这一点。
You can find a for_each_member implementation here : https://github.com/cpp-pre/json/blob/master/pre/fusion/for_each_member.hpp你可以在这里找到一个 for_each_member 实现: https : //github.com/cpp-pre/json/blob/master/pre/fusion/for_each_member.hpp
I use it to generate JSON and read structs from json as explained in my other reply here : https://stackoverflow.com/a/28580824/271781我使用它来生成 JSON 并从 json 读取结构,如我在此处的其他回复中所述: https : //stackoverflow.com/a/28580824/271781
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.