通过变量名迭代struct [英] Iterate through struct by variable name

查看:171
本文介绍了通过变量名迭代struct的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:6个月后,我刚刚看到了这个答案:索引结构是否合法?:Slava回答。我认为这是一个比这里提供的更好的解决方案,因为绝对没有未定义的行为。希望这有助于下一个人,因为我已经来不及实施。

UPDATE: 6 months later, and I just came across this answer: Is it legal to index into a struct?: Answer by Slava . I think this is a MUCH better solution than any of the ones provided here, as there is absolutely no undefined behavior. Hopefully this helps the next person, since it is already too late for me to implement.

在您发表评论之前告诉我使用数组或向量,或任何形式的容器,这是一个我不能做的事实。我知道,这将通过数组解决,否则任何解决方案都非常hacky。我很想使用容器,但我绝对不能。

我是一家非常大的公司的中级开发人员,我们正在使用公司范围的库,用于通过以太网发送数据。有多种原因可以解释为什么它不能支持数组/向量,而是使用POD结构(普通旧数据 - 字符,浮点数,整数,粗体)。我从一个浮点数组开始,我必须使用它来填充具有相同浮点数的结构。由于这个库的目的是通过以太网发送消息,我只需要进行两次迭代 - 一次在发送上,一次在接收上。所有其他时间,此数据存储为数组。我知道 - 我应该序列化数组并按原样发送它们,但我重申 - 我绝对不能。

I am a mid-level developer at a very large corporation, and we are using a company-wide library for sending data over ethernet. There are various reasons for why it cannot support arrays/vectors, and instead, uses structs of POD (Plain Old Data - chars, floats, ints, bools). I start with an array of floats that I must use to fill a struct with the same number of floats. Since the purpose of this library is to send messages over ethernet, I only need to do the iteration twice - once on the send and one on the receive. All other times, this data is stored as an array. I know - I should be serializing the arrays and sending them as is, but I repeat - I absolutely cannot.

我有一个 float [1024] ,并且必须遍历数组并填充以下结构:

I have a float[1024], and must iterate through the array and fill the following struct:

struct pseudovector
{
    float data1;
    float data2;
    float data3;
    ...
    float data1024;
}

我已经使用BOOST_PP_REPEAT BOOST_PP_SEQ_FOR_EACH_I 因此我不必写出所有1024个浮点数,它增加了可维护性/可扩展性。

I am already generating this struct with BOOST_PP_REPEAT and BOOST_PP_SEQ_FOR_EACH_I so that I do not have to write out all 1024 floats, and it increases maintainability/extensibility.

以同样的方式,我尝试通过预编译器迭代结构 ## concatination( https://stackoverflow.com/a/29020943/2066079 ),但这是在预编译时完成的,它不能用于运行时获取/设置。

In the same fashion, I have tried iterating through the struct via pre-compiler ## concatination (https://stackoverflow.com/a/29020943/2066079), but as this is done at pre-compiler time, it cannot be used for run-time getting/setting.

我已经考虑过实施反映,例如如何向C ++应用程序添加反射?思考库,但这两种方法都要求您明确写出可以反映的每个项目。在这种情况下,我不妨创建一个 std :: map< string,float> 并通过字符串/整数连接迭代for循环:

I have looked at implementing reflection such as How can I add reflection to a C++ application? and Ponder Library, but both approaches requires you to explicitly write out each item that can be reflected upon. In that case, I might as well just create a std::map<string, float> and iterate in a for loop via string/integer concatenation:

for(i=0;i<1024;i++)
{
    array[i] = map.get(std::string("data")+(i+1))
}

可以有人推荐一个更清洁的解决方案,不需要我写出超过1024行代码吗?感谢您的帮助!

Can anyone recommend a cleaner solution that does not require me to write out in excess of 1024 lines of code? Your help is appreciated!

我再说一遍 - 我绝对不能使用任何类型的数组/矢量。

推荐答案

这可能比您预期的要容易。首先,一些注意事项:

This may well be easier than you expect. First, some caveats:


  1. 按照标准,阵列保证是连续的;也就是说,它们之间没有插入填充,并且数组本身与元素类型的对齐要求对齐。

  1. Arrays are guaranteed, by the standard, to be contiguous; that is, there's no padding inserted between them, and the array itself is aligned with the alignment requirements of the element type.

结构没有这样的限制;它们可以受到任意填充。但是,给定的实现(在给定版本中)将在所有翻译单元中以相同的方式执行此操作(否则,如何使用相同的结构定义来跨翻译单元传递数据?)。通常的方法是相当理智,特别是当struct包含单个类型的成员时。对于这样的结构,对齐通常匹配成员的最大对齐,并且通常没有填充,因为所有成员具有相同的对齐。

Structs have no such restrictions; they can be subject to arbitrary padding. However, a given implementation (at a given version) will do this the same way in all translation units (otherwise, how else could the same structure definition be used to pass data across translation units?). The usual way this is done is fairly sane, especially when the struct contains only members of a single type. For such a struct, the alignment usually matches the largest alignment of the members, and there's usually no padding because all members have the same alignment.

在你的情况下,1024个浮点数的数组和1024个浮动成员的结构几乎可以具有完全相同的内存布局。 绝对不能保证标准,但您的编译器可能会记录其结构布局规则,并且您始终可以在单元测试中断言大小和对齐匹配(您确实有单元测试,对吧?)

In your case, your array of 1024 floats and your struct with 1024 float members almost certainly have exactly the same memory layout. This is absolutely not guaranteed by the standard, but your compiler may document its struct layout rules, and you can always assert the sizes and alignments match in your unit tests (you do have unit tests, right?)

鉴于这些警告,你几乎可以肯定 能够简单地 reinterpret_cast (或 memcpy )两者之间。

Given those caveats, you will almost certainly be able to simply reinterpret_cast (or memcpy) between the two.

这篇关于通过变量名迭代struct的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆