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.