我正在尝试序列化和反序列化(使用 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/