说我有一个结构:
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 ++风格的方式来访问结构得到的总和top,left,bottom和right分别?
我可以写一个循环
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。
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 替换指向成员的指针(也允许成员函数)
在不过多讨论 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)
| 归档时间: |
|
| 查看次数: |
687 次 |
| 最近记录: |