QMap :: содержит () и QMap :: value () не находит существующую пару ключ-значение

Я использую Qt 4.7.4 с MS Visual C ++ 2010.

Я использую следующий 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;
}
}
}
};

Как вы могли предположить, вся эта операция заключается в хранении файловых дескрипторов в трехмерном массиве, как в порядке. Я использую QMap, так как используется только несколько комбинаций индексов, и они могут быть большими числами.

Моя проблема:

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

а также

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

(где tFileKey — переменная T_FileMapKey) не всегда возвращает правильное значение.

При нормальных обстоятельствах QMap растет с течением времени, а это означает, что при обнаружении новой комбинации индексов открывается файл и запись добавляется в QMap.
Если я запускаю приложение в режиме отладки, надстройка Qt Visual Studio позволяет мне просматривать сохраненные пары ключ-значение. Я вижу, что запись в Watch отладки присутствует (например, {0, 32767, 0}), но два вызова функций (содержат и значение) говорят мне, что в QMap такой ключ не хранится.
Обычно такое поведение встречается после того, как QMap имеет по крайней мере 15 пар ключ-значение.

Может ли это быть ошибкой в ​​Qt 4.7.4? Что я делаю не так?

1

Решение

Ваш 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;
}
}

Эта же идея может быть легко распространена на вашу тройку.

4

Другие решения

Я думаю, что ваша проблема в вашем меньшем операторе, потому что вы никогда не сравнитесь с большим знаком.
У вас должно быть что-то подобное:

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;
}
}
}
};

Я использовал только меньше оператора, потому что вы можете не иметь других определенных

0

По вопросам рекламы [email protected]