ze strumienia do enuma

0

Cześć!

Przerobiłem sobie typ z quint8 na enuma, żeby nie trzymać co określają wartości w define'ach.
Problem pojawił się przy strumieniach, nawet jeśli enum ma określoną wielkość:

#include <QDebug>
#include <QDataStream>

enum TestEnum: quint8{
    A = 1,
    B = 2,
    C = 3
};

typedef quint8 TestScalar;
#define TESTSCALAR_A 1
#define TESTSCALAR_B 2
#define TESTSCALAR_C 3

int main(){
    char v[] = {3, 2, 3, 2, 1};
    QDataStream stream(v);

    // poprzednio
    TestScalar scalar;
    stream >> scalar;
    qDebug() << scalar;

    // nowy sposob - enum
    TestEnum testEnum;
    stream >> testEnum; // blad
    //stream >> *reinterpret_cast<quint8*>(&testEnum); // fuj
    qDebug() << testEnum;

    return 0;
}

Błąd

błąd: no match for 'operator>>' (operand types are 'QDataStream' and 'TestEnum')
     stream >> testEnum; // blad
     ~~~~~~~^~~~~~~~~~~

Jasne, QDataStream nie ma operatora >> dla TestEnum i szkoda że tak to wygląda nawet jeśli enum ma określoną wielkość
Jak to ładnie zrobić?

0

Wyklepałem coś takiego:

template <typename T>
QDataStream& operator>> (QDataStream& stream, T& t){
    using enum_type = typename std::underlying_type<T>::type;
    stream >> reinterpret_cast<enum_type&>(t);
    return stream;
}

Jakby template był tylko dla enum to byłoby cacy.

0

Nie ma potrzeby tutaj robić reinterpret_cast. Zrób static_cast na wartości zamiast reinterpret na wskaźniku.

0
Azarien napisał(a):

Nie ma potrzeby tutaj robić reinterpret_cast. Zrób static_cast na wartości zamiast reinterpret na wskaźniku.

Próbowałem i nie działa, chyba że coś źle robię:

#include <QDebug>
#include <QDataStream>
#include <type_traits>

enum TestEnum: quint8{
    A = 1,
    B = 2,
    C = 3
};

template <typename T>
QDataStream& operator>> (QDataStream& stream, T& t){
    using enum_type = typename std::underlying_type<T>::type;
    stream >> reinterpret_cast<enum_type&>(t); // ok
    //stream >> static_cast<enum_type>(t); // blad
    return stream;
}

int main(){
    char v[] = {2, 2, 3, 2, 1};
    QDataStream stream(v);

    TestEnum    testEnum;

    stream   >> testEnum;
    qDebug() << testEnum;

    return 0;
}
0

Co powiecie na to?

template<class T, class = typename std::enable_if< std::is_enum<T>::value >::type>
QDataStream& operator>> (QDataStream& stream, T& t){
    using enum_type = typename std::underlying_type<T>::type;
    stream >> reinterpret_cast<enum_type&>(t);
    return stream;
}
0

Byłbym ostrożny z przeładowywaniem globalnych operatorów. Ale to będzie działać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1