Since I found this while trying to stream an enum Type : quint8 {...} to & from QSettings, here's both ways for completeness.
template<class T, typename std::enable_if<std::is_enum<T>::value, T>::type* = nullptr>
QDataStream &operator<<(QDataStream& stream, const T &enumValue)
{
return stream << static_cast<std::underlying_type_t<T>>(enumValue);
}
template<class T, typename std::enable_if<std::is_enum<T>::value, T>::type* = nullptr>
QDataStream &operator>>(QDataStream& stream, T &enumValue)
{
std::underlying_type_t<T> val;
stream >> val;
enumValue = static_cast<T>(val);
return stream;
}
Also for QSettings the enum type AND the stream operators must be registered in Qt meta object system. Enums are registered with the Q_ENUM() (in QObject or Q_GADGET) or Q_ENUM_NS() (in namespaces), or with QT_DECLARE_METATYPE() in other cases. The stream operators need to be registered separately with qRegisterMetaTypeStreamOperators<Type>("Type"). Also note that for QFlags there are already streaming operators defined, but AFAIK they still need to be registered with qRegisterMetaTypeStreamOperators to be streamed automatically.
UPDATE:
MSVC17 with C++14 didn't like my code above, so based on @DrumM's answer, here's what works for me now with that, MinGW 7.3, gcc 6.3 & 7.3:
template <typename T>
typename std::enable_if<std::is_enum<T>::value, QDataStream&>::type
operator<<(QDataStream& stream, const T &enumValue)
{
return stream << static_cast<std::underlying_type_t<T>>(enumValue);
}
template <typename T>
typename std::enable_if<std::is_enum<T>::value, QDataStream&>::type
operator>>(QDataStream& stream, T &enumValue)
{
std::underlying_type_t<T> val;
stream >> val;
enumValue = static_cast<T>(val);
return stream;
}
// ... later
qRegisterMetaTypeStreamOperators<MyScope::MyEnum>("MyScope::MyEnum");