使用MSVC 19.0.24215.1,可以正确编译以下代码:
#include <memory>
#include <type_traits>
#include <vector>
struct NonCopyable
{
std::unique_ptr<int> field;
};
static_assert(! std::is_copy_constructible<NonCopyable>::value, "Not copyable");
class NotExported
{
private:
std::vector<NonCopyable> _member;
};
但是,当我尝试通过DLL导出此类时:
class __declspec(dllexport) Exported
{
private:
std::vector<NonCopyable> _member;
};
我收到以下错误,显然是在调用NonCopyable
的复制构造函数:
example.cpp
/opt/compiler-explorer/windows/19.00.24210/include/xutility(2316): error C2280: 'NonCopyable &NonCopyable::operator =(const NonCopyable &)': attempting to reference a deleted function
<source>(9): note: compiler has generated 'NonCopyable::operator =' here
/opt/compiler-explorer/windows/19.00.24210/include/xutility(2335): note: see reference to function template instantiation '_OutIt std::_Copy_unchecked1<_InIt,_OutIt>(_InIt,_InIt,_OutIt,std::_General_ptr_iterator_tag)' being compiled
with
[
_OutIt=NonCopyable *,
_InIt=NonCopyable *
]
/opt/compiler-explorer/windows/19.00.24210/include/vector(997): note: see reference to function template instantiation '_OutIt *std::_Copy_unchecked<NonCopyable*,NonCopyable*>(_InIt,_InIt,_OutIt)' being compiled
with
[
_OutIt=NonCopyable *,
_InIt=NonCopyable *
]
/opt/compiler-explorer/windows/19.00.24210/include/vector(980): note: while compiling class template member function 'std::vector<NonCopyable,std::allocator<_Ty>> &std::vector<_Ty,std::allocator<_Ty>>::operator =(const std::vector<_Ty,std::allocator<_Ty>> &)'
with
[
_Ty=NonCopyable
]
<source>(18): note: see reference to function template instantiation 'std::vector<NonCopyable,std::allocator<_Ty>> &std::vector<_Ty,std::allocator<_Ty>>::operator =(const std::vector<_Ty,std::allocator<_Ty>> &)' being compiled
with
[
_Ty=NonCopyable
]
<source>(17): note: see reference to class template instantiation 'std::vector<NonCopyable,std::allocator<_Ty>>' being compiled
with
[
_Ty=NonCopyable
]
Compiler returned: 2
我想了解为什么在导出类时调用对NonCopyable
的已删除副本构造函数的调用,以及如何解决此问题。
编辑:从类定义中删除__declspec(dllexport)
,而是将其放在每个公共/受保护的方法名的前面似乎可以解决此问题。我假设拥有完全导出类的模板成员会强制实例化所有成员函数,这对于std::vector
意味着实例化了复制构造函数,然后会导致此错误。