如何在C++中通过循环简化结构体成员的批量赋值操作?
在C++中批量赋值结构体成员的实现方案
原始代码与需求
结构体与设置函数
struct UpLeft { int m_up_left; }; struct UpRight { int m_up_right; }; struct DownLeft { int m_down_left; }; struct DownRight { int m_down_right; }; struct B { UpLeft up_left; UpRight up_right; DownLeft down_left; DownRight down_right; }; struct A { B b; }; int foo() { // some computation, won't always return 0. return 0; } void setUpLeft(A &a) { a.b.up_left.m_up_left = foo(); } void setUpRight(A &a) { a.b.up_right.m_up_right = foo(); } void setDownLeft(A &a) { a.b.down_left.m_down_left = foo(); } void setDownRight(A &a) { a.b.down_right.m_down_right = foo(); }
原调用方式
A a{}; setUpLeft(a); setUpRight(a); setDownLeft(a); setDownRight(a);
期望目标
替换上述重复的set函数,实现类似伪代码的批量赋值逻辑:
// pseudo-code for (x = {up_left, up_right, down_left, down_right}) { a.b.x.x_m = foo(); }
可行实现方案
方案1:Lambda数组遍历(无需修改原有结构)
通过封装每个赋值操作到lambda中,存入数组后遍历执行,无需改动现有结构体定义:
void setAll(A& a) { const auto setters = { [](A& a){ a.b.up_left.m_up_left = foo(); }, [](A& a){ a.b.up_right.m_up_right = foo(); }, [](A& a){ a.b.down_left.m_down_left = foo(); }, [](A& a){ a.b.down_right.m_down_right = foo(); } }; for (const auto& setter : setters) { setter(a); } }
调用时只需:
A a{}; setAll(a);
方案2:统一成员名+std::tuple遍历(C++17+)
如果可以统一子结构体的int成员名称(比如都改为m_value),可以结合std::tuple和std::apply实现更简洁的批量赋值:
首先修改子结构体:
struct UpLeft { int m_value; }; struct UpRight { int m_value; }; struct DownLeft { int m_value; }; struct DownRight { int m_value; };
然后实现批量赋值函数:
#include <tuple> void setAll(A& a) { auto& b = a.b; auto members = std::tie(b.up_left, b.up_right, b.down_left, b.down_right); std::apply([](auto&... args) { ((args.m_value = foo()), ...); // 折叠表达式遍历所有成员 }, members); }
方案3:重构结构体设计(最优解)
如果允许调整结构,将分散的子结构体改为数组形式,从根源上简化逻辑:
// 统一位置结构体 struct Position { int value; }; struct B { Position positions[4]; // 对应up_left、up_right、down_left、down_right }; struct A { B b; }; void setAll(A& a) { for (auto& pos : a.b.positions) { pos.value = foo(); } }
这种设计让批量操作的逻辑最清晰,也更符合C++的容器使用习惯。
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

