L.  / C++中enum(枚举)的输出写法
create

C++中enum(枚举)的输出写法

C++中enum输出一般写法

在学习C++的时候,enum一种很好表示状态的数据类型,在C++中enum类型的值为一个有名字的整数常量。如下

enum MyEnum {
    A_VAL, // 0
    B_VAL, // 1
    C_VAL, // 2
};

一开始学习的时候,我的输出写法如下

MyEnum X = A_VAL;
switch (X) {
    case A_VAL:
        std::cout << "A_VAL" <<std::endl;
        break;
    case B_VAL:
        std::cout << "B_VAL" <<std::endl;
        break;
    case C_VAL:
        std::cout << "C_VAL" <<std::endl;
        break;
}

重载运算符的写法

在学习从零开始手敲次世代游戏引擎(二十八)发现一种有意思的写法。

constexpr int32_t i32(const char* s, int32_t v) {
    return *s ? i32(s + 1, v * 256 + *s) : v; // 256 为当前字符压栈(左移8位)
}
constexpr int32_t operator"" _i32(const char* s, size_t) {
    return i32(s, 0);
}
enum SceneObjectType {
    SCENE_OBJECT_TYPE_MESH     = "MESH"_i32,
    SCENE_OBJECT_TYPE_MATRIAL  = "MATL"_i32,
    SCENE_OBJECT_TYPE_TEXTURE  = "TXTU"_i32,
    SCENE_OBJECT_TYPE_LIGHT    = "LGHT"_i32,
    SCENE_OBJECT_TYPE_CAMERA   = "CAMR"_i32,
    SCENE_OBJECT_TYPE_ANIMATOR = "ANIM"_i32,
    SCENE_OBJECT_TYPE_CLIP     = "CLIP"_i32
};

Constexpr string to constexpr int

首先利用运算符""的重载,先将四字节字符串转为4 × 8位整数。转换过程如下

其中×256即为左移8位,此时低8位皆为0,再将下个当前字符压入。类型的大小应该为字符串长度×8,此处为32。

Constexpr int to constexpr string

需要输出枚举时,我们要将整数转为字符串。

template <typename T>
T endian_net_unsigned_int(T native_number) {
    T result = 0;

    size_t i = sizeof(native_number);
    do {
        i--;
        (reinterpret_cast<uint8_t*>(&result))[i] = native_number & UCHAR_MAX;
        native_number >>= CHAR_BIT;
    } while (i != 0);
    return result;
}

std::ostream& operator<<(std::ostream& out, SceneObjectType type) {
    int32_t n = static_cast<int32_t>(type);
    // little endian, read bit from end;
    n       = endian_net_unsigned_int<int32_t>(n);
    char* c = reinterpret_cast<char*>(&n);

    for (int i = 0; i < sizeof(int32_t); i++) {
        out << *c++;
    }

    return out;
}

首先将枚举转为32位整型,在按照字节读取(此处UNIX和WIN均为小端储存,读取正序的int32_t需要转为逆序的char*,即在内存上为HSEM),由于没有结束符'\0' 故而需按字符输出。(有结束符时,类型位int64_t)

总的来说,思路为"" 重载输出整型常量,按位正序储存,输出时再将其读取并逆序储存(操作系统原因,小端储存),再转为字符串类型,按字符输出。