Seite 1 von 1

[gelöst] QMultiHash & QVariant - compiler error C2665

Verfasst: 26. Februar 2007 14:40
von abelmi
Hallo,
folgender Code erzeugt mir den Compilerfehler C2665:

Kann mir jemand von euch vielleicht einen Tips geben, wie ich diesen Fehler verhindern kann?

Code: Alles auswählen

QVariant key;
QMultiHash< QVariant, QWidget* > test;
QList< QWidget* > values = test.values( key );
Der Schlüssel für den Hash muss aber vom Typ QVariant sein, da erst bei Erstellung des Hashes der Typ des Schlüssels feststeht.

Qt Version: 4.1.4
Compiler: Microsoft Visual Studio .NET 2005

Fehlerausgabe des Compilers:

Code: Alles auswählen

c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(743) : error C2665: 'qHash' : none of the 16 overloads could convert all the argument types
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(37): could be 'uint qHash(char)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(38): or 'uint qHash(uchar)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(39): or 'uint qHash(signed char)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(40): or 'uint qHash(ushort)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(41): or 'uint qHash(short)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(42): or 'uint qHash(uint)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(43): or 'uint qHash(int)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(44): or 'uint qHash(ulong)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(52): or 'uint qHash(long)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(53): or 'uint qHash(quint64)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(61): or 'uint qHash(qint64)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(62): or 'uint qHash(QChar)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(63): or 'uint qHash(const QByteArray &)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(64): or 'uint qHash(const QString &)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/kernel/qabstractitemmodel.h(323): or 'uint qHash(const QModelIndex &)'
        c:\qt\4.1.4_static\include\qtgui\../../src/gui/itemviews/qitemselectionmodel.h(162): or 'uint qHash(const QItemSelectionRange &)'
        while trying to match the argument list '(const QVariant)'
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(741) : while compiling class template member function 'QHashNode<Key,T> **QHash<Key,T>::findNode(const Key &,uint *) const'
        with
        [
            Key=QVariant,
            T=QWidget *
        ]
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(576) : while compiling class template member function 'QList<T> QHash<Key,T>::values(const Key &) const'
        with
        [
            T=QWidget *,
            Key=QVariant
        ]
        c:\qt\4.1.4_static\include\qtcore\../../src/corelib/tools/qhash.h(785) : see reference to class template instantiation 'QHash<Key,T>' being compiled
        with
        [
            Key=QVariant,
            T=QWidget *
        ]
        ..\..\src\Models\ExtTreeProxyModel.cpp(97) : see reference to class template instantiation 'QMultiHash<Key,T>' being compiled
        with
        [
            Key=QVariant,
            T=QWidget *
        ]

Verfasst: 26. Februar 2007 15:01
von Christian81
Das wird wohl nicht so ganz funktionieren wie Du es Dir vorgestellt hast.
QVariant ist dein key. Um etwas in einem QHash zu speichern, muss man aus dem key einen hash erstellen. D.h. Du musst die Funktion "uint qhash(QVariant)" implementieren, und zwar so dass keine Kollisionen entstehen. Immer 0 zurückgeben ist also nicht.

Verfasst: 26. Februar 2007 16:02
von abelmi
danke Christian für die schnelle Antwort.

ich versuche deinen Vorschlag umzusetzen und diese Methode implementieren.

ich werde meine Erfahrungen/Fortschritte hier für die Nachwelt schreiben...

Verfasst: 27. Februar 2007 11:23
von abelmi
Hier meine Implementierung einer qHash-Methode für den Datentyp QVariant.

Code: Alles auswählen

#include <QHash.h>

uint qHash( const QVariant & var )
{
    if ( !var.isValid() || var.isNull() )
        return -1;

    switch ( var.type() )
    {
        case QVariant::Int:
                return qHash( var.toInt() );
            break;
        case QVariant::UInt:
                return qHash( var.toUInt() );
            break;
        case QVariant::Bool:
                return qHash( var.toUInt() );
            break;
        case QVariant::Double:
                return qHash( var.toUInt() );
            break;
        case QVariant::LongLong:
                return qHash( var.toLongLong() );
            break;
        case QVariant::ULongLong:
                return qHash( var.toULongLong() );
            break;
        case QVariant::String:
                return qHash( var.toString() );
            break;
        case QVariant::Char:
                return qHash( var.toChar() );
            break;
        case QVariant::StringList:
                return qHash( var.toString() );
            break;
        case QVariant::ByteArray:
                return qHash( var.toByteArray() );
            break;
        case QVariant::Date:
        case QVariant::Time:
        case QVariant::DateTime:
        case QVariant::Url:
        case QVariant::Locale:
        case QVariant::RegExp:
                return qHash( var.toString() );
            break;
        case QVariant::Map:
        case QVariant::List:
        case QVariant::BitArray:
        case QVariant::Size:
        case QVariant::SizeF:
        case QVariant::Rect:
        case QVariant::LineF:
        case QVariant::Line:
        case QVariant::RectF:
        case QVariant::Point:
        case QVariant::PointF:
            // not supported yet
            break;
       case QVariant::UserType:
        case QVariant::Invalid:
        default:
            return -1;
    }

    // could not generate a hash for the given variant
    return -1;
}

Verfasst: 27. Februar 2007 13:10
von Christian81
nicht return -1 sondern Q_ASSERT(0) sonst denkt man der QVariant-Datentyp funktioniert was nicht der Fall ist.

Verfasst: 28. Februar 2007 10:02
von abelmi
danke für den Tip und deine Hilfe Christian.