Visual Studio C++-std::映射插入失败

Visual Studio C++ - std::map insertion failing

本文关键字:插入 失败 映射 Visual C++-std Studio      更新时间:2023-10-16

我有以下一段在GCC中工作的代码。

//StyleEditor.h
typedef std::set<HWND> PanelSet;
class DLL_EXPORT StyleEditor
{
public:
StyleEditor(HWND mainWnd, std::wstring instanceName);
~StyleEditor();
int Edit(std::wstring styleName);
BOOL DoInitDialog(HWND hwndDlg, bool updatePos);
BOOL DoCommand(HWND hwndDlg, WPARAM wParam, LPARAM lParam);
BOOL DoNotify(HWND hwndDlg, LPARAM lParam);
BOOL DoColourChooser(COLORREF* colour, HWND hwndDlg);
BOOL DoLoad(HWND hwndDlg);
BOOL DoSwitch(HWND hwndDlg);
void DoSaveAs(HWND hwndDlg);
static INT_PTR CALLBACK StyleEditorDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
LPCTSTR GetTemplate();
private:
std::map< HTREEITEM, std::tr1::shared_ptr<PanelSet> > panelMap;
std::wstring tmpFile, instanceName;
RECT colourRect;
COLORREF colourBackground, colourForeground, colourSelected, colourFrame, colourFont;
COLORREF colourFrom, colourTo, colourBorder;
HWND mainWnd, toolWnd;
GUIINFO guiInfo, origGuiInfo, defaultGuiInfo;
std::wstring style, font, origStyle;
HBITMAP hbmColourBackground, hbmColourForeground, hbmColourSelected, hbmColourFrame, hbmColourFont;
HBITMAP hbmColourFrom, hbmColourTo, hbmColourBorder;
std::wstring DoSaveStyle(HWND hwndDlg, std::wstring fileName);
BOOL DoDefaults(HWND hwndDlg);
void BuildPanelMap(HWND hwndDlg);
void ClearPanelMap();
void ShowPanel(HTREEITEM panel);
HTREEITEM hitemOpacity, hitemColor, hitemGradient, hitemMisc;
};

//StyleEditor.cpp
TVINSERTSTRUCT tvInsert;
tvInsert.hParent = NULL;
tvInsert.hInsertAfter = TVI_ROOT;
tvInsert.item.mask = TVIF_TEXT;
tvInsert.item.pszText = (WCHAR*)TEXT("Opacity");
hitemOpacity = TreeView_InsertItem(treeWnd, &tvInsert);
panelMap.insert(std::pair<HTREEITEM, PanelSet*>(hitemOpacity, new PanelSet));

在Visual Studio 2013中,它在编译过程中爆炸:

1>  StyleEditor.cpp
1>d:programmingemergedesktopemergedesktophgtipsourceemergestyleenginestyleeditor.h(90): warning C4251: 'StyleEditor::panelMap' : class 'std::map<HTREEITEM,std::shared_ptr<PanelSet>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' needs to have dll-interface to be used by clients of class 'StyleEditor'
1>          with
1>          [
1>              _Kty=HTREEITEM
1>  ,            _Ty=std::shared_ptr<PanelSet>
1>          ]
<snip - a lot more of the same warning>
1>d:programmingemergedesktopemergedesktophgtipsourceemergestyleenginestyleeditor.cpp(491): error C2664: 'void std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::insert(std::initializer_list<std::pair<const _Kty,_Ty>>)' : cannot convert argument 1 from 'std::pair<HTREEITEM,PanelSet *>' to 'std::pair<const _Kty,_Ty> &&'
1>          with
1>          [
1>              _Kty=HTREEITEM
1>  ,            _Ty=std::shared_ptr<PanelSet>
1>  ,            _Pr=std::less<HTREEITEM >
1>  ,            _Alloc=std::allocator<std::pair<const HTREEITEM ,std::shared_ptr<PanelSet>>>
1>          ]
1>          and
1>          [
1>              _Kty=HTREEITEM
1>  ,            _Ty=std::shared_ptr<PanelSet>
1>          ]
1>          Reason: cannot convert from 'std::pair<HTREEITEM,PanelSet *>' to 'std::pair<const _Kty,_Ty>'
1>          with
1>          [
1>              _Kty=HTREEITEM
1>  ,            _Ty=std::shared_ptr<PanelSet>
1>          ]
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
<snip - more of the same error>

我通过将DLL_EXPORTS转移到要导出的单个方法而不是类本身来修复警告:

class StyleEditor
{
public:
DLL_EXPORT StyleEditor(HWND mainWnd, std::wstring instanceName);
DLL_EXPORT ~StyleEditor();
DLL_EXPORT int Edit(std::wstring styleName);
DLL_EXPORT BOOL DoInitDialog(HWND hwndDlg, bool updatePos);
DLL_EXPORT BOOL DoCommand(HWND hwndDlg, WPARAM wParam, LPARAM lParam);
DLL_EXPORT BOOL DoNotify(HWND hwndDlg, LPARAM lParam);
DLL_EXPORT BOOL DoColourChooser(COLORREF* colour, HWND hwndDlg);
DLL_EXPORT BOOL DoLoad(HWND hwndDlg);
DLL_EXPORT BOOL DoSwitch(HWND hwndDlg);
DLL_EXPORT void DoSaveAs(HWND hwndDlg);
DLL_EXPORT static INT_PTR CALLBACK StyleEditorDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
DLL_EXPORT LPCTSTR GetTemplate();
private:
std::map< HTREEITEM, std::tr1::shared_ptr<PanelSet> > panelMap;
std::wstring tmpFile, instanceName;
RECT colourRect;
COLORREF colourBackground, colourForeground, colourSelected, colourFrame, colourFont;
COLORREF colourFrom, colourTo, colourBorder;
HWND mainWnd, toolWnd;
GUIINFO guiInfo, origGuiInfo, defaultGuiInfo;
std::wstring style, font, origStyle;
HBITMAP hbmColourBackground, hbmColourForeground, hbmColourSelected, hbmColourFrame, hbmColourFont;
HBITMAP hbmColourFrom, hbmColourTo, hbmColourBorder;
std::wstring DoSaveStyle(HWND hwndDlg, std::wstring fileName);
BOOL DoDefaults(HWND hwndDlg);
void BuildPanelMap(HWND hwndDlg);
void ClearPanelMap();
void ShowPanel(HTREEITEM panel);
HTREEITEM hitemOpacity, hitemColor, hitemGradient, hitemMisc;
};

但是VS在CCD_ 2中的CCD_。我在调用中尝试了std::shared_ptr的各种迭代,如下所示:

panelMap.insert(std::pair<HTREEITEM, std::shared_ptr<PanelSet>>(hitemOpacity, new PanelSet));
panelMap.insert(std::pair<HTREEITEM, std::shared_ptr<PanelSet>>(hitemOpacity, std::make_shared<PanelSet>(new PanelSet))); //appears to work at first, but errors in VC's memory header show up instead

在这一点上我没有想法。我甚至不知道该如何搜索这个错误,因为错误消息太长太乱了。如果您能就这段代码到底出了什么问题(请记住GCC没有问题)以及如何修复它提供任何建议,我将不胜感激。

您似乎没有尝试显而易见的(?)事情。

这是你的地图

std::map< HTREEITEM, std::tr1::shared_ptr<PanelSet> > panelMap;

你试过

panelMap.insert(std::pair<HTREEITEM, PanelSet*>(hitemOpacity, new PanelSet));    

panelMap.insert(std::pair<HTREEITEM, std::shared_ptr<PanelSet>>(hitemOpacity, new PanelSet));

但出于某种原因,不是这个

panelMap.insert(std::pair<HTREEITEM, std::tr1::shared_ptr<PanelSet>>(hitemOpacity, new PanelSet));

我不知道在这种情况下这是否能解决你的问题,但这里有一个建议,可以避免将来出现这样的问题。

首先,我会为地图声明一个typedef

typedef std::map< HTREEITEM, std::tr1::shared_ptr<PanelSet> > PanelMapType;

然后使用每个地图在插入时所具有的value_type typedef

panelMap.insert(PanelMapType::value_type(hitemOpacity, new PanelSet));

通过这种方式,可以确保插入到地图中的类型是正确的。此外,如果类型不匹配导致错误,它将引用您的代码,而不是map::insert函数内部的代码。