我有以下代码可以在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没有问题)以及如何修复它。
答案 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
函数的内容中的代码。