1

MS Visual C++ 2010 で Qt 4.7.4 を使用しています。

次の QMap を使用しています。

QMap<T_FileMapKey, HANDLE>  m_oMapHistHandle; 

ここで、T_FileMapKey は次のように定義されます。

typedef struct tagT_FileMapKey
{
    int iSubscriptIdx;
    int iFilterIdx_1;
    int iFilterIdx_2;
} T_FileMapKey;

全体を進めるために、< 演算子をオーバーロードしました。

bool operator< (const T_FileMapKey& tVal1, const T_FileMapKey& tVal2)
{
    if(tVal1.iSubscriptIdx < tVal2.iSubscriptIdx)
    {
        return true;
    }
    else
    {
        if(tVal1.iFilterIdx_1 < tVal2.iFilterIdx_1)
        {
            return true;
        }
        else
        {
            if (tVal1.iFilterIdx_2 < tVal2.iFilterIdx_2)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}; 

ご想像のとおり、この操作全体は、ファイル ハンドルを 3 次元配列のような順序で格納することです。私は QMap を使用しています。これは、インデックスの組み合わせが少数しか使用されておらず、それらが多数になる可能性があるためです。

私の問題は次のとおりです。

if (INVALID_HANDLE_VALUE == m_oMapCurrHandle.value(tFileKey, fdInvalidHandle))
....

if (false == m_oMapHistHandle.contains(tFileKey))
....

(tFileKey は T_FileMapKey 変数です) は常に正しい値を返すとは限りません。

通常の状況では、QMap は時間の経過とともに大きくなります。つまり、新しいインデックスの組み合わせが検出されると、ファイルが開かれ、エントリが QMap に追加されます。アプリケーションをデバッグ モードで起動すると、Qt Visual Studio アドインを使用して、保存されているキーと値のペアを確認できます。デバッグ ウォッチにエントリ ({0, 32767, 0} など) があることがわかりますが、2 つの関数呼び出し (contains と value) から、QMap にそのようなキーが保存されていないことがわかります。通常、この動作は、QMap に少なくとも 15 個のキーと値のペアがある場合に発生します。

これは Qt 4.7.4 のバグでしょうか? 何が間違っていますか?

4

2 に答える 2

4

あなたoperator<は間違っています。operator<説明するために、だけのために書くより単純な理由を考えてみましょうpair<int, int>。あなたのバージョンは次のように実装されています:

bool operator<(const pair<int, int>& lhs, const pair<int, int>& rhs) 
{
    if (lhs.first < rhs.first) {
        return true; // (1)
    }
    else if (lhs.second < rhs.second) {
        return true; // (2)
    }
    else {
        return false; // (3)
    }
}

だから{1,4}< {2,3}(1)のために。でも{2,3}{1,4}(2)のせいで!したがってoperator<、順序付けを確立しない で終わります。

辞書編集的な比較を確立する最も簡単な方法は、各用語を順番に完全に処理することです。

bool operator<(const pair<int, int>& lhs, const pair<int, int>& rhs)
{
    if (lhs.first != rhs.first) {
        return lhs.first < rhs.first;
    }
    else {
        return lhs.second < rhs.second;
    }
}

同じ考え方をトリプルに簡単に拡張できます。

于 2015-01-14T15:07:39.013 に答える
0

あなたの問題は、より大きな符号と比較することがないため、少ない演算子にあると思います。あなたはそのようなものを持っている必要があります:

bool operator< (const T_FileMapKey& tVal1, const T_FileMapKey& tVal2)
{
    if(tVal1.iSubscriptIdx < tVal2.iSubscriptIdx)
    {
        return true;
    }
    else if (tVal2.iSubscriptIdx < tVal1.iSubscriptIdx)
    {
        return false ;
    }
    else
    {
        if(tVal1.iFilterIdx_1 < tVal2.iFilterIdx_1)
        {
            return true;
        }
        else if (tVal2.iFilterIdx_1 < tVal1.iFilterIdx_1 )
        {
            return false ;
        }
        else
        {
            if (tVal1.iFilterIdx_2 < tVal2.iFilterIdx_2)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}; 

他に定義されていない可能性があるため、少ない演算子のみを使用しました

于 2015-01-14T15:08:55.243 に答える