简体   繁体   中英

How do I access list of structs with an integer argument (c++)?

I have a series of structs:

const struct weapon Dagger = { 1, 40, 5, 20, 30, "Dagger" };
const struct weapon Sword = { 2, 35, 25, 40, 60, "Sword" };
const struct weapon Axe = { 4, 50, 10, 70, 80, "Axe" };
const struct ...

I want to arrange them so I can access each one by integer. I am trying to build a function that takes int x and int y as arguments, and returns the indexed struct's data. For example, if the function takes 2 and 3 , respectively, the value 35 from the weapon struct will be returned. Intuitively, I imagined the function body looking something like return weapon[x].y , although this does not work.

I do not know how to do this. The best alternative I can see is to use arrays instead of structs. Should I do this instead?

If you are only after the numeric data, then you could use two arrays: one for the data itself, and one for accessor function pointers:

struct weapon
{
    int val;
    int hp;
    int foo;
    // ...
    std::string name;
 };

const weapon w[] = {
  { 1, 40, 5, 20, 30, "Dagger" },
  { 2, 35, 25, 40, 60, "Sword" },
  { 4, 50, 10, 70, 80, "Axe" },
};

using accessor = int weapon::*;
const accessor acc[] = {
  &weapon::val,
  &weapon::hp,
  &weapon::foo,
  // ...
};

Now to look up property j in weapon i (both zero-indexed), you could say:

w[i].*acc[j]

Alternatively, you could perhaps represent your data as an array of pairs:

std::pair<const char*, std::array<int, 5>> w_alt[] = {
  { "Dagger", { 1, 40,  5, 20, 30 } },
  { "Sword",  { 2, 35, 25, 40, 60 } },
  { "Axe",    { 4, 50, 10, 70, 80 } },
};

Now the i th weapon's anme is w_alt[i].first , and its j th property is w_alt[i].second[j] .

For the first part of your question (selecting weapon based on index), using an array is a simple option, eg:

std::array<weapon, 3> const weapons =
{ { 1, 40, 5, 20, 30, "Dagger" }
, { 2, 35, 25, 40, 60, "Sword" }
, { 4, 50, 10, 70, 80, "Axe" }
};

Then, if you want, you can make specific references:

weapon const &Sword = weapons[1];

or make indices which you'll use to access the array:

enum weapon_id { Dagger, Sword, Axe };

// ...
do_something( weapons[Sword] );

Using std::array instead of a C-style array weapon const weapons[] = has a drawback that you can't deduce the dimension, but it has other benefits that make up for this.


For the second part, you may add a function that looks up the weapon properties by index. For example:

int weapon_lookup_number(weapon const &w, int index)
{
    switch(index)
    {
    case 0: return w.id;
    case 1: return w.power;
    // etc.
    }
}

with another function for looking up the string.

Using template specialization it'd be possible to have a function that looks up the member by index and evaluates to the correct type, however that would only work in the case of the index being known at compile-time.

If you want a container that has indexed access, you probably want std::vector . Something like:

std::vector<weapon> WeaponVector;

If your struct becomes:

struct weapon {
    int val;
    int hp;
    int foo;
    // ...
    std::string name;
};

You could use a std::vector<weapon> Weapons to store the struct s, sort it using:

std::sort(Weapons.begin(), Weapons.end(),
          [](const Weapons& w1,const Weapons& w2) -> bool { return w1.val > w2.val; }))

and access them using the vector indexes like: weapons[some_num].hp; , where some_num will correspond to the wanted val .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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