首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QMap::contains()和QMap::value()找不到现有的键值对

QMap::contains()和QMap::value()找不到现有的键值对
EN

Stack Overflow用户
提问于 2015-01-14 14:58:39
回答 2查看 1.5K关注 0票数 1

我使用QT4.7.4和MS VisualC++ 2010。

我使用的是以下QMap:

代码语言:javascript
复制
QMap<T_FileMapKey, HANDLE>  m_oMapHistHandle; 

其中T_FileMapKey被定义为:

代码语言:javascript
复制
typedef struct tagT_FileMapKey
{
    int iSubscriptIdx;
    int iFilterIdx_1;
    int iFilterIdx_2;
} T_FileMapKey;

为了使整个工作顺利进行,我重载了<操作符:

代码语言:javascript
复制
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;
            }
        }
    }
}; 

正如您可能预测的那样,整个操作是将文件句柄存储在像order这样的三维数组中。我使用的是一个QMap,因为只使用了几个索引组合,而且它们可能是大量的。

我的问题是:

代码语言:javascript
复制
if (INVALID_HANDLE_VALUE == m_oMapCurrHandle.value(tFileKey, fdInvalidHandle))
....

代码语言:javascript
复制
if (false == m_oMapHistHandle.contains(tFileKey))
....

(其中tFileKey是T_FileMapKey变量)并不总是返回正确的值。

在正常情况下,QMap是随着时间的推移而增长的,这意味着如果遇到新的索引组合,就会打开文件并将条目添加到QMap中。如果我以调试模式启动应用程序,外接程序允许我查看存储的键值配对。我可以看到调试监视中的条目是存在的(例如{0,32767,0}),但是两个函数调用(包含和值)告诉我,QMap没有存储这样的键。通常,在QMap至少有15个键值对之后才会遇到这种行为。

这可能是Qt 4.7.4中的一个bug吗?做错什么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-14 15:07:39

你的operator<是错的。为了解释这一点,让我们考虑一个简单的原因,即为operator<编写pair<int, int>。您的版本是这样实现的:

代码语言:javascript
复制
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<

建立辞典比较最简单的方法是依次完整地处理每一个词:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2015-01-14 15:08:55

我认为你的问题是在你的较少的接线员,因为你从来没有比较大的符号。你应该有这样的东西:

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27945864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档