c++ - (反)序列化枚举类

标签 c++ qt5 enum-class qdatastream

我正在尝试序列化和反序列化(使用 QDataStream 但这与这里无关) enum class变量:

enum class Type : char
{
    Trivial,
    Complex
};

序列化很简单:

QDataStream &operator<<(QDataStream &stream, Type type)
{
    return stream << static_cast<char>(type);
}

但是反序列化不是:

QDataStream &operator>>(QDataStream &stream, Type &type)
{    
    return stream >> static_cast<char &>(type);
}

显然是 static_cast引用enum class不允许对其基础类型的引用。此外,“显而易见”的解决方案:

QDataStream &operator>>(QDataStream &stream, Type &type)
{    
    return stream >> reinterpret_cast<char &>(type);
}

实际上可能是非法的并且未由标准 according to the answer to this question 定义因为等效表达式 return stream >> (*static_cast<char *>(static_cast<void *>(&type)));在那里被宣布为非法(或者更确切地说没有由标准定义)。如果是这种情况,我需要这样做:

QDataStream &operator>>(QDataStream &stream, Type &type)
{    
    char c = 0;
    stream >> c;
    type = static_cast<Type>(c);
    return stream;
}

这不太漂亮,是 4 行而不是 1 行等等。对于我来说,对于这样一个(看似)简单的事情来说似乎没有必要。

我的问题:reinterpret_cast或等效的static_cast通过void*当引用 enum class 时确实非法(标准未定义)变量到其基础类型的引用?

最佳答案

您可以编写一个模板函数,该函数允许您为每个 operator>> 编写 1 行您定义的。

template <class UT, class S, class E> S& DeserializeEnumClassValue(S &s, E &e)
{
    UT temp;
    s >> temp;
    e = static_cast<E>(temp);
    return s;
}

像这样使用它:

QDataStream &operator>>(QDataStream &stream, Type &type)
{    
    return DeserializeEnumClassValue<char>(stream, value);
}

但这可以使用 std::underlying_type ( https://en.cppreference.com/w/cpp/types/underlying_type ) 进行改进,因为可以在编译时获取它。

如果您采用这种方法,那么您也应该对 operator<< 执行类似的操作使维护更容易。

关于c++ - (反)序列化枚举类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54055248/

相关文章:

c++ - 重载 << 运算符和继承类

c++ - 与 Valgrind 一起运行时,malloc 返回 null

php - 基于 C++ 代码在 PHP 中创建字节数据并将其传递到套接字

c++ - 布局时 QGraphicsItem::pos 返回 0

c++ - 验证整数是某个枚举类项 (C++11)

c++ - 按下 F5 且源代码已过时时启用自动构建

c++ - 使用 QList<QVariantMap> 作为 QML ListView 的模型

c++ - Qt5 中 QX11EmbedWidget 的对应物是什么?

c++ - std::get 使用枚举类作为模板参数

c++ - 在 Boost Test 中使用枚举类