如何将结构体直接嵌入insert调用插入std::map无需提前声明变量
我已查阅过相关问题,目前我通过如下方式填充我的map:
SPECIAL_EVENT_S sEvent{}; sEvent.datEvent = datEvent; sEvent.strEvent = strDescription; sEvent.strLocation = strLocation; sEvent.iForeignLanguageGroupMenuID = dwForeignLanguageGroup; sEvent.eSRREventType = static_cast<EventTypeSRR>(dwEventTypeSRR); sEvent.eMWBEventType = static_cast<EventTypeMWB>(dwEventTypeSMR); // Duration sEvent.datEventStartTime = datEventStartTime; sEvent.datEventFinishTime = datEventFinishTime; sEvent.bEventAllDay = bEventAllDay; // Reminder sEvent.bSetReminder = bSetReminder; sEvent.iReminderUnitType = iReminderUnitType; sEvent.iReminderInterval = iReminderInterval; // Videoconference events sEvent.iImageWidthPercent = wImageWidthPercent; sEvent.strImagePath = strImagePath; sEvent.strTextBeforeImage = strTextBeforeImage; sEvent.strTextAfterImage = strTextAfterImage; sEvent.eType = eType; m_mapSpecialEvents.insert( { datEvent.Format(_T("%Y-%m-%d")), sEvent } );
我能否不先创建实际的SPECIAL_EVENT_S变量,直接将该结构体嵌入insert函数调用中完成插入操作?
SPECIAL_EVENT_S结构体定义如下:
using SPECIAL_EVENT_S = struct tagSpecialEvent { COleDateTime datEvent; CString strEvent; CString strLocation; // Foreign Language Group EventTypeSRR eSRREventType{}; EventTypeMWB eMWBEventType{}; int iForeignLanguageGroupMenuID{}; // Duration COleDateTime datEventStartTime; COleDateTime datEventFinishTime; BOOL bEventAllDay{}; // Reminder BOOL bSetReminder{}; int iReminderUnitType{}; int iReminderInterval{}; // Videoconference events int iImageWidthPercent{}; CString strImagePath; CString strTextBeforeImage; CString strTextAfterImage; CChristianLifeMinistryDefines::VideoConferenceEventType eType{}; };
复现步骤
MFC对话框应用
对话框头文件代码:
#include <map> using SPECIAL_EVENT_S = struct tagSpecialEvent { CString strEvent; }; using SpecialEventDataMap = std::map<CString, SPECIAL_EVENT_S>;
添加私有成员变量:
private: SpecialEventDataMap m_mymap;
在对话框的OnInitDialog方法中添加如下代码:
m_mymap.insert(_T("1234-56-78"), { .strEvent });
上述代码无法正常运行。
解答
你写的代码报错有两个核心原因:
std::map::insert没有接收键、值两个单独参数的重载,你需要把键值对包装成std::pair或者用花括号包裹的{键, 值}形式传参- 你用的C++版本不支持你写的这种不完整的指定初始化语法,指定初始化需要给成员显式赋值,正确写法是
.strEvent = 你要赋值的内容
你要的直接嵌入结构体插入的写法完全可以实现,适配你场景的代码示例如下:
m_mapSpecialEvents.insert( { datEvent.Format(_T("%Y-%m-%d")), { datEvent, strDescription, strLocation, static_cast<EventTypeSRR>(dwEventTypeSRR), static_cast<EventTypeMWB>(dwEventTypeSMR), dwForeignLanguageGroup, datEventStartTime, datEventFinishTime, bEventAllDay, bSetReminder, iReminderUnitType, iReminderInterval, wImageWidthPercent, strImagePath, strTextBeforeImage, strTextAfterImage, eType } } );
如果你用的是C++20及以上版本,还可以用指定初始化让代码可读性更高,不需要严格按结构体成员声明顺序赋值:
m_mapSpecialEvents.insert( { datEvent.Format(_T("%Y-%m-%d")), { .datEvent = datEvent, .strEvent = strDescription, .strLocation = strLocation, .iForeignLanguageGroupMenuID = dwForeignLanguageGroup, .eSRREventType = static_cast<EventTypeSRR>(dwEventTypeSRR), .eMWBEventType = static_cast<EventTypeMWB>(dwEventTypeSMR), .datEventStartTime = datEventStartTime, .datEventFinishTime = datEventFinishTime, .bEventAllDay = bEventAllDay, .bSetReminder = bSetReminder, .iReminderUnitType = iReminderUnitType, .iReminderInterval = iReminderInterval, .iImageWidthPercent = wImageWidthPercent, .strImagePath = strImagePath, .strTextBeforeImage = strTextBeforeImage, .strTextAfterImage = strTextAfterImage, .eType = eType } } );
你复现用的最小示例修改后可以正常运行的写法如下:
m_mymap.insert({ _T("1234-56-78"), { .strEvent = _T("测试事件内容") } });
如果你的编译器不支持C++20的指定初始化,就按成员声明顺序赋值即可:
m_mymap.insert({ _T("1234-56-78"), { _T("测试事件内容") } });
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

