Aqui está o trecho de código
#include<memory>
#include<unordered_map>
struct
__declspec(dllexport)
Foo {
std::unordered_map<const int*, std::unique_ptr<int>> foo;
};
Foo foo();
que falha assim :
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
Vejo que o problema é o fato de std::unique_ptr
não ser copiável, como está implícito, por exemplo, em 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>'
, mas por que a capacidade de cópia é exigida apenas no Windows e somente com o dllexport
?
Na base de código de onde isso foi extraído, __declspec(dllexport)
está a expansão de uma macro que se expande para valores diferentes em outras plataformas, por exemplo, __attribute__ ((visibility("default")))
no Linux, caso em que o código é compilado perfeitamente.
O MSVC deseja dllexportar o construtor de cópia e o operador de atribuição de cópia para sua estrutura (porque você declarou toda a estrutura como dllexport) e aparentemente tenta gerar implementações padrão para eles, mesmo que devam ser excluídos. Eu diria que é um bug do MSVC. Excluí-los explicitamente resolve o problema de demonstração .