1

I have a similar question here but the context of this new question is different.

Background

I have this variable: PublisherMap m_mapPublishers;

The definition of PublisherMap is:

using PublisherMap = std::map<CString, S_DEMO_ENTRY_EX>;

The code

I have this method that reads the map and populates a CListBox:

bool CChristianLifeMinistryPersonalCopiesDlg::InitPublishersGrid()
{
    try
    {
        m_lbPublishers.ResetContent();

        for (auto & mapPublisher : m_mapPublishers)
        {
            bool bInclude = false;

            if (m_iDisplayMode == DISPLAY_EVERYONE)
                bInclude = true;
            else if (m_iDisplayMode == DISPLAY_BROTHER && mapPublisher.second.eGender == GENDER_MALE)
                bInclude = true;
            else if (m_iDisplayMode == DISPLAY_SISTER && mapPublisher.second.eGender == GENDER_FEMALE)
                bInclude = true;

            if (bInclude && m_bLimitDisplay)
            {
                CString strTemp;
                if (!m_mapSSAssignedPublishers.Lookup(mapPublisher.first, strTemp))
                    bInclude = FALSE;
            }

            if (bInclude)
            {
                int i = m_lbPublishers.AddString(mapPublisher.first);
                m_lbPublishers.SetItemData(i, MAKEWPARAM(mapPublisher.second.eGender, mapPublisher.second.eAppointed));

            }
        }
    }
    catch (_com_error e)
    {
        LPCTSTR szError = e.ErrorMessage();
        AfxMessageBox(szError);
        return false;
    }
    catch (CException* e)
    {
        e->Delete();
        AfxMessageBox(_T("CException"));
        return false;
    }

    m_iSelectMode = SELECT_NONE;
    UpdateData(FALSE);

    return true;
}

Notice that I use item data:

m_lbPublishers.SetItemData(i, 
    MAKEWPARAM(mapPublisher.second.eGender, mapPublisher.second.eAppointed));

It works absolutely fine. If I was using a CPtrArray I would have assigned the actual structure object pointers against each entry in the list box.

The question

I don't know the mechanics of std::map enough. Is there any safe way to directly associate each entry from the map (mapPublisher) against each list box entry so that I can later access it?

I realise I could take the text of the list box entry and then find it in the map and get it that way. But if there is a more direct way to tie the two together?

4

2 回答 2

4

std::map被指定为从不移动现有元素的关联容器,请参见[associative.reqmts]/9

insertandemplace成员不应影响迭代器和对容器的引用的有效性,并且成员erase应仅使迭代器和对已擦除元素的引用无效。

在实践中,它通常被实现为红黑树。

因此,保留指向现有元素的指针是安全的,只要它们的生命周期超过指针的生命周期。

请注意,如果您切换到std::unordered_map(哈希映射),您将失去该保证。


设置:

    m_lbPublishers.SetItemDataPtr(i, &mapPublisher.second);

要检索:

    auto psEntry = (S_DEMO_ENTRY_EX*)m_lbPublishers.GetItemDataPtr(i);

CListBox::GetItemDataPtr()返回void*,因此需要强制转换。

于 2018-03-28T08:31:56.643 回答
2

只要映射的节点没有被破坏/删除,您就可以将指向映射数据类型的指针直接传递给CListBox::SetItemDataPtr.

因此,在您的情况下,访问S_DEMO_ENTRY_EX并使用指针 using&mapPublisher.second是可以的。

这是由 STL 的规则保证的

于 2018-03-28T08:20:59.987 回答