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

时间:2018-06-07 16:46:17

标签: c++

我有一个结构Foo;

typedef struct {

    int bar;
    char baz;

} Foo;

假设我然后将Foo数组声明为;

Foo* arr = new Foo[300];

然后继续用循环初始化每个成员。我非常希望得到所有成员的数组吧;

int* barr_arr = ...

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

既然我们事先知道了内存布局,我们可以利用这样一个事实:如果我们知道对齐的话,我们知道每个成员的地址吗?

5 个答案:

答案 0 :(得分:2)

  

最有效的方法是什么?有没有办法利用内存布局,这样我就不需要遍历整个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; });

答案 1 :(得分:2)

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

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;
}

答案 2 :(得分:1)

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

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

这消除了为bar数组分配新缓冲区的需要,这取决于正在处理的Foo个数,可能会节省大量内存。

我还要注意的是,如果您不是在低级别工作而且实际上不需要int*但可以使用std::vector<int>,那么@R Sahu& #39;答案可能是一个更合适的解决方案。

答案 3 :(得分:1)

目标推动了设计。

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

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

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

答案 4 :(得分:1)

如果向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