Visual Studio C ++ - std :: map插入失败

时间:2013-11-18 06:46:48

标签: c++ gcc dll stl visual-studio-2013

我有以下代码可以在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:\programming\emergedesktop\emergedesktophgtip\source\emergestyleengine\styleeditor.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:\programming\emergedesktop\emergedesktophgtip\source\emergestyleengine\styleeditor.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仍然在panelMap.insert的{​​{1}}行错误输出。我在调用中尝试了StyleEditor.cpp的各种迭代,如下所示:

std::shared_ptr

此时我已经没有想法了。我甚至不确定如何搜索此错误,因为错误消息是如此冗长和混乱。我很欣赏有关此代码究竟出现什么问题的任何建议(请记住GCC没有问题)以及如何修复它。

1 个答案:

答案 0 :(得分:3)

你似乎没有尝试明显的(?)事情。

这是你的地图

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函数的内容中的代码。