c++qtenumsqmetaobject

Q_ENUM to ostream


In a project is custom logger which I would like to extend to write enum values as qDebug() does. It there some easy way doing so?

Here is something I thought may work(and it doesn't):

template <typename T>
typename QtPrivate::QEnableIf<QtPrivate::IsQEnumHelper<T>::Value, std::ostream>::Type
operator<<(std::ostream& os, T enumValue)
{
    const QMetaObject* mo = qt_getEnumMetaObject(enumValue);
    int enumIdx = mo->indexOfEnumerator(qt_getEnumName(enumValue));
    return os << mo->enumerator(enumIdx).valueToKey(enumValue);
}

class MyObjet : public QObject
{
    Q_OBJECT
public:
    enum class Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete };
    Q_ENUM(Action)
    explicit MyObjet(QObject* parent);
    void myFunction(Action a)
    {
        std::count << "Action is:" << a << std::endl;
    }
};

Solution

  • This is the insertion operator overload, I put it in a header file called qtenum2ostream.h:

    #ifndef QTENUM2OSTREAM_H
    #define QTENUM2OSTREAM_H
    
    #include <QMetaEnum>
    
    template<typename T>
    typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, std::ostream  &>::type
    operator<<(std::ostream & o, const T & t)
    {
        const QMetaObject* metaobject = qt_getEnumMetaObject(t);
        int enumindex = metaobject->indexOfEnumerator(qt_getEnumName(t));
        o << metaobject->enumerator(enumindex).valueToKey(static_cast<int>(t));
        return o;
    }
    
    #endif // QTENUM2OSTREAM_H
    

    You can now use it in your example class:

    #include "qtenum2ostream.h"
    #include <iostream>
    
    #include <QObject>
    
    class MyObject : public QObject {
        Q_OBJECT
    public:
        enum class Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete };
        Q_ENUM(Action)
        void myFunction(Action a)
        {
            std::cout << "Action is:" << a << std::endl;
        }
    };