W jaki sposób dodać wartości zależne od indeksów podanych w enumie?

0

Temat być może trochę zagmatwanie napisany, ale chodzi o to, że mam enum

#define bit(x) 1 << x

#define ZwrocWartosc1 5
#define ZwrocWartosc2 3
#define ZwrocWartosc3 15

enum JakisEnum
{
    Wartosc1 = bit(1),
    Wartosc2 = bit(2),
    Wartosc3 = bit(3)
};

unsigned int ZwrocWartosc(JakisEnum enum)
{
    switch(enum)
    {
        case Wartosc1: return ZwrocWartosc1 ; break;
        case Wartosc2: return ZwrocWartosc2 ; break;
        case Wartosc3: return ZwrocWartosc3 ; break;
    }

    return 0;
}

I chciałbym aby funkcja ZwrocWartosc mogła przyjmować parametr jak na przykład JakisEnum::Wartosc1 | JakisEnum::Wartosc2. Powinna ona wtedy zwrócić 8
Niestety tych #define ZwrocWartoscX nie mogę usunąć ani zamienić na nic innego.

Trochę nad tym myślałem ale większość moich pomysłów po prostu okazała się niewypałem.

W jaki sposób mógłbym to wykonać?

0

Przykład z mojego projektu:

namespace MechLocations
{
    enum Location
    {
        None = 0,
        Head = 1,
        CenterTorso = 2,
        LeftTorso = 4,
        LeftArm = 8,
        LeftLeg = 16,
        RigthTorso = 32,
        RightArm = 64,
        RightLeg = 128,
        All = 256
    };
}

i gdzieś tam w kodzie:

weapon.allowedLocations = static_cast<MechLocations::Location>(weapon.allowedLocations | MechLocations::All);//to jest typu MechLocations::location
0

Tylko w ten sposób uzyskam kolejne wartości bitowe (indexy) zamiast wartości przypisane do tych bitów.

gdy podam w kodzie jako parametr Wartosc1, funkcja zwraca ZwrocWartosc czyli nie BIT(1) tylko wartość zdefiniowaną jako 3. Jeśli ta wartość jest 3 to znaczy, że trzeba wykonać jakąś rzecz. Jeśli do funkcji podamy kombinacje wartości Wartosc1 | Wartosc2 wtedy powinno zwrócić ZwrocWartosc1 + ZwrocWartosc2 czyli 3 + 5 = 8 wtedy inna funkcja wie, że powinna wykonać jakąś rzecz, która kryje się pod numerem 3 oraz, która kryje się pod numerem 5.

Mógłbym to zrobić ifem w taki sposób

unsigned int ZwrocWartosc(JakisEnum enum)
{
    switch(enum)
    {
        case Wartosc1: return ZwrocWartosc1 ; break;
        case Wartosc2: return ZwrocWartosc2 ; break;
        case Wartosc3: return ZwrocWartosc3 ; break;
    }

    if(Wartosc1 | Wartosc2) return ZwrocWartosc1 + ZwrocWartosc2;
    else if(Wartosc1 | Wartosc3) return ZwrocWartosc1 + ZwrocWartosc3;
    else if(Wartosc2 | Wartosc3) return ZwrocWartosc2 + ZwrocWartosc3;
    else if(Wartosc1 | Wartosc2 | Wartosc3) return ZwrocWartosc1 + ZwrocWartosc2 + ZwrocWartosc3;

    return 0;
}

ale gdy tych wartości będą setki to wtedy robi nam się nieskończenie długi if

0

A gdzie tam nieskończony, ot 1 linijka per wartość JakisEnum. A oto dowód:

#include <iostream>

using namespace std;

enum JakisEnum
{
    Wartosc1 = 5,
    Wartosc2 = 3,
    Wartosc3 = 15
};
 
unsigned int zwrocWartosc(JakisEnum enumValue)
{
     unsigned int result = (enumValue & JakisEnum::Wartosc1) == Wartosc1 ? Wartosc1 : 0 ;
     result += (enumValue & JakisEnum::Wartosc2) == Wartosc2 ? Wartosc2 : 0;
     result += (enumValue & JakisEnum::Wartosc3) == Wartosc3 ? Wartosc3 : 0;
     return result;
}

int main()
{
    cout<< zwrocWartosc(static_cast<JakisEnum>(Wartosc1 | Wartosc2 | Wartosc3));

    return 0;
}

https://onlinegdb.com/r1ATzXMaQ

1 użytkowników online, w tym zalogowanych: 0, gości: 1