E. Pratt
E. Pratt

Reputation: 136

C++ using specific class and enum scope within switch statement

Take note of the following scenario:

class Packet {
public:
    enum Opcode {
        S2C_JOIN_GAME,
        S2C_LEAVE_GAME
    } opcode;
    std::string payload;
};

class Client{
public:
    void readPacket(Packet packet);
};

void Client::readPacket(Packet packet){
    switch(packet.opcode){
        case Packet::Opcode::S2C_JOIN_GAME:
            //call some function to handle this case
            break;
        case Packet::Opcode::S2C_LEAVE_GAME:
            //call another function to handle this case
            break;
    }
}

Within Client::readPacket, I need to check the opcode and call a specific function dependent on it. In my project I have a lot of different opcodes. Can I use a specific scope within my switch statement so I don't need to type Packet::Opcode every time?

For example:

void Client::readPacket(Packet packet){
    switch(packet.opcode){
        using namespace Packet::Opcode; //illegal, is there something similar?
        using namespace Packet; // also illegal
        case S2C_JOIN_GAME: 
            //do stuff.
            break;
        case S2C_LEAVE_GAME:
            //do stuff.
            break;
    }
}

The code above will not compile because Packet is not a namespace. Is there an alternative way to get the same behavior in the example above without giving my enum type global scope?

Upvotes: 0

Views: 1137

Answers (4)

Mustafa Kemal GILOR
Mustafa Kemal GILOR

Reputation: 156

With C++20, it is now possible to use "using" keyword in switch scope.


#include <cstdint>

enum class my_enumeration : std::uint8_t{
    type1,
    type2,
    type3
};

/* ... */

void foo(my_enumeration e) {
  switch(e){
     using enum my_enumeration;
     case type1:
     case type2: 
     case type3:
        break;
  }
}


Upvotes: 2

user7860670
user7860670

Reputation: 37503

If item names get too long you can define an appropriate type alias:

void Client::readPacket(Packet packet)
{
    using Opcode = Packet::Opcode;
    switch(packet.opcode)
    {
        case Opcode::S2C_JOIN_GAME: 
            //do stuff.
            break;
        case Opcode::S2C_LEAVE_GAME:
            //do stuff.
            break;
    }
}

Upvotes: 3

Chiel
Chiel

Reputation: 6194

The answer is no. I don't see the problem of your code, I find it better to be clear, than to be short.

Upvotes: 2

Rakete1111
Rakete1111

Reputation: 48938

Opcode is not a scoped enum:

auto opcode = Packet::S2C_JOIN_GAME; // ok

But there is no way to remove Packet, because you are not in Packet's class scope and it is not a namespace, as you correctly mentioned.

Upvotes: 2

Related Questions