将 std::map 项设置为 CListBox 的项数据
Setting std::map items as itemdata of CListBox
>我在这里有一个类似的问题,但这个新问题的上下文是不同的。
背景
我有这个变量:PublisherMap m_mapPublishers;
PublisherMap
的定义是:
using PublisherMap = std::map<CString, S_DEMO_ENTRY_EX>;
代码
我有这种方法可以读取地图并填充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;
}
请注意,我使用项目数据:
m_lbPublishers.SetItemData(i,
MAKEWPARAM(mapPublisher.second.eGender, mapPublisher.second.eAppointed));
它工作绝对正常。如果我使用的是CPtrArray
我会针对列表框中的每个条目分配实际的结构对象指针。
问题
我对std::map
的机制了解不够。是否有任何安全的方法将映射(mapPublisher
)中的每个条目直接与每个列表框条目相关联,以便以后可以访问它?
我意识到我可以获取列表框条目的文本,然后在地图中找到它并以这种方式获得它。但是,如果有更直接的方法将两者联系在一起呢?
std::map
被指定为从不移动现有元素的关联容器,请参阅 [associaciative.reqmts]/9:
insert
和emplace
成员不得影响迭代器和对容器的引用的有效性,erase
成员应仅使迭代器和对已擦除元素的引用无效。
在实践中,它通常被实现为一棵红黑树。
因此,保留指向现有元素的指针是安全的,只要它们的生存期超过指针的生存期。
请注意,如果您切换到std::unordered_map
(哈希映射),您将失去该保证。
要设置:
m_lbPublishers.SetItemDataPtr(i, &mapPublisher.second);
要检索:
auto psEntry = (S_DEMO_ENTRY_EX*)m_lbPublishers.GetItemDataPtr(i);
CListBox::GetItemDataPtr()
返回void*
因此需要强制转换。
只要映射的节点没有被销毁/删除,您就可以将指向映射数据类型的指针直接传递给CListBox::SetItemDataPtr
。
因此,在您的情况下,访问S_DEMO_ENTRY_EX
并使用指针使用&mapPublisher.second
是可以的。
这是由STL规则保证
的- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何对点云数据进行排序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 将 std::map 项设置为 CListBox 的项数据