简体   繁体   English

C ++迭代结构

[英]C++ iterating a struct

Is it possible to iterate through a struct? 是否可以遍历一个结构?

For example 例如

struct team{
   int player1;
   int player2;
   int player3;
   int player4;
   ...
   int player99; 
   int size = 99;
}

then run a for loop to set or access foo 1-4? 然后运行for循环来设置或访问foo 1-4?

i guess pseudocode would look something like 我猜伪代码看起来像

for(int i = 0; i < size; i++){
    player i = (i+1); 
 }

A more simplified explanation if that doesnt make sense is I Just want to be able to go through each variable without having to hard code player1 = 1; 一个更简单的解释,如果没有意义,我只是希望能够通过每个变量而不必硬编码player1 = 1; player2 =2. player2 = 2。

One way is to put the players/elements into an array: 一种方法是将player / elements放入一个数组:

struct Team {
    static int const size = 99;
    int players[size];
};

And then: 接着:

for(int i = 0; i < size; ++i)
    int player = players[i];

I would propose to use container instead of many variables, for example you could use std::array or std::vector . 我建议使用容器而不是许多变量,例如你可以使用std::arraystd::vector This way it will be trivial to iterate, much easier to make a copy. 这样,迭代就会变得微不足道,更容易复制。 But also it's better from design point of view: in case you decide to change the number of players it will be much easier to change the container rather than add/remove many fields 但从设计的角度来看也更好:如果您决定更改播放器的数量,更改容器将更容易,而不是添加/删除许多字段

To answer your question as you've asked it, I believe that you can use the pre-compiler macro Pack (the exact phrase depends on your compiler) to guarantee the structure of the memory used to create an instance of your struct. 为了回答你提出的问题,我相信你可以使用预编译器宏包(确切的短语取决于你的编译器)来保证用于创建结构实例的内存结构。 And then you technically could increment a pointer to move through it... if you're mad. 然后你在技术上可以增加一个指针来移动它...如果你生气了。 That would be a very poor way to do and not at all guaranteed to work on different compilers or even different days of the week. 这将是一种非常糟糕的方式,并且完全不能保证在不同的编译器上工作,甚至在一周中的不同日期工作。 No what you want is a data structure to do the job for you; 没有您想要的是一种数据结构来为您完成这项工作。 they come with a 100% cash-back guarantee! 他们提供100%现金返还保证!

The most basic structure to do this with is a fixed size array, eg: 最基本的结构是固定大小的数组,例如:

struct team
{
    int players[99]; //an array
    int manager;
    int coach;
    string teamName;
    //etc etc
}

Then to access your players 然后访问你的球员

team myTeam;
for(int i(0); i < 99; ++i)
{
    myTeam.players[i]; //do whatever
}

The limitation of an array is that you cannot change its size once it's created. 数组的限制是创建数组后就无法更改其大小。 So if you try 所以,如果你尝试

myTeam.players[99]; //accessing invalid memory - the array values are 0 - 98

More advanced 更先进

If you need a data structure that can change size after it's created, eg you might want to add a few more players to your team at some point in the future. 如果您需要一个可以在创建后更改大小的数据结构,例如,您可能希望在将来的某个时刻向您的团队添加更多玩家。 Then you can use a dynamic data structure such as the std::vector or the std::deque or std::list 然后,您可以使用动态数据结构,例如std :: vectorstd :: dequestd :: list

You can define pointer to member, like pointer to member function: 您可以定义指向成员的指针,例如指向成员函数的指针:

  typedef int team::*member_t;

You can have array of pointers to all your members: 您可以拥有指向所有成员的指针数组:

  static member_t member[size];

With this approach defining member function to iterate over all members is easy: 通过这种方法,定义成员函数以遍历所有成员很容易:

  template <class F>
  void for_each(F f)
  {
     for (int i = 0; i < size; ++i)
       f(this->*member[i]);
  }

And with using of preprocessor macro - you can have in one place definition of all members, in other definition of pointer to members - so you will not make any mistake with changing their order. 并且使用预处理器宏 - 您可以在一个地方定义所有成员,在其他指向成员的指针中 - 这样您就不会在更改其顺序时出错。 See full code: 查看完整代码:

struct team {
#define TEAM_MEMBERS(prefix,suffix) \
  prefix player1 suffix, \
  prefix player2 suffix, \
  prefix player3 suffix

  int TEAM_MEMBERS(,);
  static const int size = 3;
  typedef int team::*member_t;
  static member_t member[size];
  template <class F>
  void for_each(F f)
  {
     for (int i = 0; i < size; ++i)
       f(this->*member[i]);
  }
};
team::member_t team::member[team::size] = {
  TEAM_MEMBERS(&team::,)
};

And some test: 还有一些测试:

#include <iostream>

int main() {
  team t = { 0 };
  t.for_each([](int m) { std::cout << m << "\n"; }); // prints 0,0,0
  int n = 0;
  t.for_each([&n](int& m) { m = n++; });
  t.for_each([](int m) { std::cout << m << "\n"; }); // prints 0,1,2
  t.player2 = 7;
  t.for_each([](int m) { std::cout << m << "\n"; }); // prints 0,7,2
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM