為什么修改時(shí)會(huì)分離本地QMultiMap?

提供一些背景信息:在我的項(xiàng)目中,我在QMap::detach_helper中放置了一個(gè)調(diào)試斷點(diǎn),因?yàn)槲蚁肟纯丛陔[式共享qmap由于疏忽而分離時(shí)是否可以發(fā)現(xiàn)任何事件,例如,在可以使用constFind時(shí)使用find。我沒想到會(huì)經(jīng)常碰到它,因?yàn)槲抑饕峭ㄟ^const引用傳遞容器(作為旁注,顯然有一個(gè)叫做“clazy”的工具來查找這樣的東西)。

然后我查看了一些觸發(fā)分離的內(nèi)部Qtv5.9.3代碼。stacktrace顯示我們正在從insertMulti函數(shù)的第一行分離,該函數(shù)在contexts上調(diào)用:

// return true if accepted (consumed)
bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
{
    QMap<Qt::GestureType, int> types;
    QMultiMap<QObject *, Qt::GestureType> contexts;
    QWidget *w = receiver;
    typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
    if (!w->d_func()->gestureContext.isEmpty()) {
        for(ContextIterator it = w->d_func()->gestureContext.constBegin(),
            e = w->d_func()->gestureContext.constEnd(); it != e; ++it) {
            types.insert(it.key(), 0);
            contexts.insertMulti(w, it.key());
        }
    }
    // find all gesture contexts for the widget tree
    w = w->isWindow() ? 0 : w->parentWidget();
    while (w)
    {
        for (ContextIterator it = w->d_func()->gestureContext.constBegin(),
             e = w->d_func()->gestureContext.constEnd(); it != e; ++it) {
            if (!(it.value() & Qt::DontStartGestureOnChildren)) {
                if (!types.contains(it.key())) {
                    types.insert(it.key(), 0);
                    contexts.insertMulti(w, it.key()); // Why does this trigger a detach?
                }
            }
        }
        if (w->isWindow())
            break;
        w = w->parentWidget();
    }
    return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
}

為什么本地QMultiMapcontexts——從來都不是copied-——會(huì)隱式共享并需要分離?


My Theory

這可能不相關(guān),但contexts的大小在該行為零。

我猜分離是由某種與空映射相關(guān)的優(yōu)化引起的,但我不確定。我確實(shí)注意到,通過將調(diào)試斷點(diǎn)放在QMap::detach_helper的部分中,只對(duì)non-empty映射執(zhí)行(也就是說,在條件if (d->header.left)中),得到的命中率要少得多

? 最佳回答:

Q(Multi)Map不會(huì)在每次插入時(shí)分離,而僅在映射尚未初始化時(shí)在第一次插入時(shí)分離:

QMultiMap<int, int> mm;
mm.insert(42, 43);  // detach_helper is called because the container needs to be initialized
mm.insert(43, 44);  // detach_helper is not called
主站蜘蛛池模板: 男人免费视频一区二区在线观看| 日韩视频免费一区二区三区| 国产av一区最新精品| 麻豆一区二区免费播放网站| 亚洲国产AV无码一区二区三区| 久久久久人妻精品一区三寸| 春暖花开亚洲性无区一区二区| 无码人妻一区二区三区免费视频 | 无码一区二区三区免费视频| 精品国产一区二区三区久久影院| 亚洲高清成人一区二区三区| 亚洲av一综合av一区| 精品国产一区二区三区久久狼| 国产精品一区二区久久精品无码| 国产成人久久精品一区二区三区| 一区二区三区无码被窝影院| 一区在线免费观看| 在线精品国产一区二区| 免费在线视频一区| 无码日韩精品一区二区免费暖暖| 久热国产精品视频一区二区三区| 午夜精品一区二区三区在线视| 无码AV中文一区二区三区| 日韩精品一区二区三区在线观看l| 99国产精品一区二区| 怡红院AV一区二区三区| 国产成人无码一区二区三区在线| 中文字幕av日韩精品一区二区| 国产伦精品一区二区三区视频猫咪| 无码少妇一区二区性色AV| 无码喷水一区二区浪潮AV| 国产av一区二区三区日韩| 波多野结衣在线观看一区| 在线中文字幕一区| 久久一区二区免费播放| 国产日产久久高清欧美一区| 亚洲av无码一区二区三区乱子伦| 三级韩国一区久久二区综合| 亚洲国产av一区二区三区丶| 夜夜添无码一区二区三区| 白丝爆浆18禁一区二区三区 |