这是代码片段
#include<memory>
#include<unordered_map>
struct
__declspec(dllexport)
Foo {
std::unordered_map<const int*, std::unique_ptr<int>> foo;
};
Foo foo();
失败如下:
C:/data/msvc/14.39.33321-Pre/include\list(1299): error C2679: binary '=': no operator found which takes a right-hand operand of type 'const std::pair<const int *const ,std::unique_ptr<int,std::default_delete<int>>>' (or there is no acceptable conversion)
C:/data/msvc/14.39.33321-Pre/include\utility(315): note: could be 'std::pair<_Kty,_Ty> &std::pair<_Kty,_Ty>::operator =(volatile const std::pair<_Kty,_Ty> &)'
with
[
_Kty=const int *,
_Ty=std::unique_ptr<int,std::default_delete<int>>
]
C:/data/msvc/14.39.33321-Pre/include\list(1299): note: 'std::pair<_Kty,_Ty> &std::pair<_Kty,_Ty>::operator =(volatile const std::pair<_Kty,_Ty> &)': cannot convert argument 2 from 'const std::pair<const int *const ,std::unique_ptr<int,std::default_delete<int>>>' to 'volatile const std::pair<_Kty,_Ty> &'
with
[
_Kty=const int *,
_Ty=std::unique_ptr<int,std::default_delete<int>>
]
C:/data/msvc/14.39.33321-Pre/include\list(1299): note: Reason: cannot convert from 'const std::pair<const int *const ,std::unique_ptr<int,std::default_delete<int>>>' to 'volatile const std::pair<_Kty,_Ty>'
with
[
_Kty=const int *,
_Ty=std::unique_ptr<int,std::default_delete<int>>
]
... see linked example for complete error
我确实看到问题是std::unique_ptr
不可复制的事实,正如所暗示的那样,例如,通过Reason: cannot convert from 'const std::pair<const int *const ,std::unique_ptr<int,std::default_delete<int>>>' to 'volatile const std::pair<_Kty,_Ty>'
,但为什么仅在 Windows 上需要可复制性并且仅使用dllexport
?
在从中提取的代码库中,__declspec(dllexport)
是宏的扩展,该宏在其他平台上扩展为不同的值,例如__attribute__ ((visibility("default")))
在 Linux 上,在这种情况下代码编译得很好。
MSVC 希望 dllexport 结构体的复制构造函数和复制赋值运算符(因为您将整个结构体声明为 dllexport),并且它似乎尝试为它们生成默认实现,即使它们应该被删除。我想说这是一个 MSVC 错误。显式删除它们可以解决演示问题。