C++ 遍历结构体的成员

Ame*_*mer 7 c++

说我有一个结构:

struct Boundary {
  int top;
  int left;
  int bottom;
  int right;
}
Run Code Online (Sandbox Code Playgroud)

和一个向量

std::vector<Boundary> boundaries;
Run Code Online (Sandbox Code Playgroud)

什么是最C ++风格的方式来访问结构得到的总和topleftbottomright分别?

我可以写一个循环

for (auto boundary: boundaries) {
  sum_top+=boundary.top;
  sum_bottom+=boundary.bottom;
  ...
}
Run Code Online (Sandbox Code Playgroud)

这似乎有很多重复。当然,我可以这样做:

std::vector<std::vector<int>> boundaries;

for (auto boundary: boundaries) {
  for(size_t i=0; i<boundary.size();i++) {
    sums.at(i)+=boundary.at(i)
  }
}
Run Code Online (Sandbox Code Playgroud)

但是后来我会丢失所有有意义的结构成员名称。有没有办法让我可以编写类似以下函数的内容:

sum_top=make_sum(boundaries,"top");
Run Code Online (Sandbox Code Playgroud)

反射似乎不是 C++ 中的一个选项。我愿意使用 C++ 到版本 14。

pet*_*hen 5

std::accumulate(boundaries.begin(), boundaries.end(), 0, 
 [](Boundary const & a, Boundary const & b) { return a.top + b.top); });
Run Code Online (Sandbox Code Playgroud)

(IIRC 边界常量 & 可以auto在 C++17 中“d”)

这并不使它对于特定元素具有通用性,实际上,由于缺乏反射,它不容易概括。

不过,有几种方法可以减轻您的痛苦;

您可以使用指向成员的指针,这对您的 szenario 很好,但不是很 c-plusplus-y:

int Sum(vector<Boundary>const & v, int Boundary::*pMember)
{
   return std::accumulate( /*...*/, 
     [&](Boundary const & a, Boundary const & b)
     {
        return a.*pMember + b.*pMember;
     });
}

int topSum = Sum(boundaries, &Boundary::top);
Run Code Online (Sandbox Code Playgroud)

(对于指向成员的指针,请参见例如此处:指向类数据成员 "::*" 的指针

你也可以使这个通用(任何容器,任何成员类型),你也可以用 lambda 替换指向成员的指针(也允许成员函数)


Tob*_*zel 3

在不过多讨论 C++ 对象的内存布局的情况下,我建议用“reference-getters”替换成员,这会向结构中添加一些样板代码,但除了替换之外top不需要top()对使用方式进行任何更改结构体成员。

struct Boundary {
   std::array<int, 4> coordinates;
   int& top() { return coordinates[0]; }
   const int& top() const { return coordinates[0]; }
   // ...
 }

 Boundary sum{};
 for (auto b : boundaries) {
   for (auto i = 0; i < 4; ++i) {
      sum.coordinates[i] += b.coordinates[i];
   }
 }
Run Code Online (Sandbox Code Playgroud)