在循环中按顺序遍历成员变量
Traversing member variables sequentially in a loop
这是我在循环中按顺序遍历类/结构中成员变量的实现,下面是一个典型的例子。我的实现看起来很难看,看起来像是用蛮力实现的。如何改进或推广。我想像链接列表的节点->下一个或数组中那样遍历变量?征求意见。提前感谢大师。
typedef struct {
string name;
string address;
string phone;
void set(const int idx, string str) {
idx == 0 ? name = str : idx == 1 ? address = str : phone = str;
}
void print() const {
std::cout << name << "-" << address << "-" << phone << 'n';
}
} Person ;
int main()
{
Person p;
string str;
stringstream ss{ "John London 9735048383" };
int idx = 0;
while (std::getline(ss, str, ' ')) {
p.set(idx++,str); // Traversing the member variables. The member variables will take turn to set their values in order.
}
p.print();
}
已编辑:所有成员变量的类型相同。
您也可以使用指向成员的指针,而不是使用宏。请注意,在C++中,您不必使用typedef struct
struct Person {
std::string name;
std::string address;
std::string phone;
void print() const {
std::cout << name << "-" << address << "-" << phone << 'n';
}
};
int main()
{
Person p;
std::string str;
std::stringstream ss{ "John London 9735048383" };
std::vector<std::string(Person::*)> members = { &Person::name, &Person::address, &Person::phone };
for (auto it = members.begin(); std::getline(ss, str, ' ') && it != members.end(); ++it) {
std::invoke(*it, p) = str;
// Traversing the member variables. The member variables will take turn to set their values in order.
}
p.print();
}
您可以使invoke
稍微更容易接受,前提是您不关心停止流错误。
for (auto member : members)
{
std::getline(ss, invoke(member, p), ' ');
}
如果你真的想要一些可以通用的东西,并且你愿意使用宏,你可以使用更高阶的宏。在您的情况下,您将首先添加一个宏,声明结构的所有字段及其索引:
#define FOREACH_FIELD(OP)
OP(0, name)
OP(1, address)
OP(2, phone)
然后,您将使用此宏来实现Person
结构:
struct Person {
#define DECLARE_VAR(index, name) std::string name;
FOREACH_FIELD(DECLARE_VAR)
#undef DECLARE_VAR
void setField(int i, const std::string& value) {
switch (i) {
#define SET_FIELD(index, name) case index: name = value; break;
FOREACH_FIELD(SET_FIELD)
#undef SET_FIELD
};
}
void print() {
#define PRINT_FIELD(index, name)
std::cout << #name << ": '" << name << "'" << std::endl;
FOREACH_FIELD(PRINT_FIELD)
#undef PRINT_FIELD
}
};
它看起来很难看,我建议你在采用上述技术之前仔细考虑一下。一般来说,C++中避免使用宏。它使代码更难阅读,但如果你有很多字段,那么,你可以使用它。它可以使代码更易于维护。毕竟,要添加新字段,只需更新FOREACH_MACRO
即可。
小心使用此技巧
std::array似乎按照用户463035818的建议对我有效,这似乎是迄今为止最简单的解决方案。std::map将具有额外的优势,可以和别名一起使用。
typedef struct {
std::array<string, 3> data;
void print() const {
std::cout << data[0] << "-" << data[1] << "-" << data[2] << 'n';
}
} Person ;
int main()
{
Person p;
string str;
stringstream ss{ "John London 9735048383" };
int idx = 0;
while (std::getline(ss, str, ' ')) {
p.data[idx++] = str;
}
p.print();
}
相关文章:
- 有什么方法可以遍历结构吗
- 在循环中按顺序遍历成员变量
- 遍历模板参数
- 在遍历处理程序的向量时注册和注销处理程序
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 遍历并行数组以确定C++中的最大数字
- 遍历顺序由 std::文件系统directory_iterator给出
- 遍历链表时的无限循环
- 遍历unordered_map向量
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- C++声明双链表,使用两个 for 循环双向遍历列表并打印
- Rapidjson 遍历并获取复杂 JSON 对象成员的值
- 在使用 In Order 遍历成员函数时引发异常(堆栈溢出)时出现问题
- 如何调用遍历类层次结构的成员函数
- 是否可以在 constexpr 函数中遍历枚举成员,因此值为 constexpr
- 如何遍历类的实例集合并访问其模板成员
- 在向量中遍历结构成员时出错
- 遍历对类成员的引用,简单且最好是可重用的
- 使用引用的数组 (C++) 遍历类成员
- C++:遍历对象的所有成员?