访问数组中所有结构的成员

Access a member of all structs in an array

本文关键字:结构 成员 数组 访问      更新时间:2023-10-16

>我有一个结构体Foo;

typedef struct {
int bar;
char baz;
} Foo;

假设我随后声明一个 Foo 数组为;

Foo* arr = new Foo[300];

并继续使用循环初始化每个成员。我非常希望能够获得所有成员的数组栏;

int* barr_arr = ...

最有效的方法是什么?有没有办法利用内存布局,这样我就不需要遍历整个 Foo 数组?

由于我们事先知道内存布局,如果我们在对齐方面很聪明,我们是否可以利用我们知道每个成员地址的事实?

最有效的方法是什么?有没有办法利用内存布局,这样我就不需要遍历整个 Foo 数组?

我认为没有循环就没有余地做到这一点。可以使用std::transform简化代码,但std::transform会循环。

另外,我建议使用std::vector而不是使用new分配数组。

std::vector<Foo> arr(300);
....

std::vector<int> bArr(arr.size());
std::transform(arr.begin(), arr.end(), bArr.begin(), [] -> (Foo const& f) { return f.bar; });

初始化第一个数组时,可以获取指向每个元素内字段的指针,并将其存储在单独的数组中。

struct Foo
{
int bar;
float baz;
};
const int SIZE = 5;
Foo foos[SIZE];
int *bars[SIZE];
for(int c = 0; c < SIZE; c++) {
foos[c].bar = c;
foos[c].baz = c;
bars[c] = &foos[c].bar; // Grab pointer to field
}
for(int c = 0; c < SIZE; c++) {
std::cout << "Bar Value: " << *bars[c] << std::endl;
}

如果Foo通常存在于数组中,并且经常需要访问相应的bars 和baz数组,我建议重新设计您的数据结构以更好地适应您的问题。显然,我们没有阅读激发这个问题的代码,但鉴于提供的信息,我可能会建议如下:

struct FooArray {
int* bars;
char* bazes;
size_t n_elements;
};

这样就无需为bar数组分配新的缓冲区,根据正在处理的Foo数量,这可能会节省大量内存。

我还要指出,如果你不是在低水平上工作,实际上不需要int*,但可以用std::vector<int>来做,那么@R Sahu的答案可能是一个更合适的解决方案。

目标驱动设计。

如果您的主要用途是连续传递所有bar成员(对于baz成员也是如此(,则创建单独的容器:

std::vector<int> bar;
std::vector<char> baz;

然后bar作为数组传递很简单:只需使用bar.data().

如果将一个构造函数添加到Foo中,该构造函数的大小与数组的大小相同,则只能有一个Foo对象。然后,您可以访问整个矢量数据或带有下标的单个元素:

#include <iostream>
#include <vector>
#include <memory>
struct Foo
{
std::vector<int> bars;
std::vector<char> bazs;
std::size_t size;
Foo(size_t size, int bar = 0, char baz = 0) :
bars(size, bar), bazs(size, baz), size{size}
{
}
auto operator[](size_t n)
{
// if (n >= size) ...
struct
{
int &bar;
char &baz;
} temp{ bars[n], bazs[n] };
return temp;
}
};

int main()
{
Foo arr(30, 100, 'a'); // 30 items
std::cout << arr[29].bar << std::endl;
std::cout << arr[29].baz << std::endl;
std::cout << arr.bars[29] << std::endl;
std::cout << arr.bazs[29] << std::endl;
std::unique_ptr<Foo> arr2 = std::make_unique<Foo>(25, 10, 'b'); // 25 items
std::cout << arr2->operator[](15).bar << std::endl;
std::cout << arr2->operator[](15).baz << std::endl;
arr2->bars[15] = 11;
std::cout << arr2->bars[15] << std::endl;
arr2->bazs[15] = 'c';
std::cout << arr2->bazs[15] << std::endl;
return 0;
}

演示:https://ideone.com/TiVwOT

100
a
100
a
10
b
11
c