Cap*_*ous 16 c++ visual-c++ c++11
我最近不得不改变几个类的链接规范并遇到了问题.其中两个类包含std::map
a std::unique_ptr
作为值类型.链接更改后,编译器开始抱怨"无法访问类'std :: unique_ptr <_Ty>''中声明的私有成员错误.
任何人都知道为什么只有在提供导出规范或有解决方案时才会发生这种情况?
示例代码:
#include <map>
struct SomeInterface
{
virtual ~SomeInterface() = 0;
};
// This class compiles with no problems
struct LocalClass
{
std::map<int, std::unique_ptr<SomeInterface>> mData;
};
// This class fails to compile
struct __declspec(dllexport) ExportedClass
{
std::map<int, std::unique_ptr<SomeInterface>> mData;
};
Run Code Online (Sandbox Code Playgroud)
编译器输出:
c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(163): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
with
[
_Ty=SomeInterface
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\memory(2347) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
with
[
_Ty=SomeInterface
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(195) : see reference to function template instantiation 'std::_Pair_base<_Ty1,_Ty2>::_Pair_base<const int&,_Ty2&>(_Other1,_Other2)' being compiled
with
[
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Other1=const int &,
_Other2=std::unique_ptr<SomeInterface> &
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xmemory(208) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2>::pair<const _Kty,_Ty>(std::pair<_Ty1,_Ty2> &)' being compiled
with
[
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Kty=int,
_Ty=std::unique_ptr<SomeInterface>
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xmemory(280) : see reference to function template instantiation 'void std::allocator<_Ty>::construct<std::pair<_Ty1,_Ty2>&>(std::pair<_Ty1,_Ty2> *,_Other)' being compiled
with
[
_Ty=std::pair<const int,std::unique_ptr<SomeInterface>>,
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Other=std::pair<const int,std::unique_ptr<SomeInterface>> &
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtree(592) : see reference to function template instantiation 'void std::_Cons_val<std::allocator<_Ty>,_Ty,std::pair<_Ty1,_Ty2>&>(_Alloc &,std::pair<_Ty1,_Ty2> *,std::pair<_Ty1,_Ty2>)' being compiled
with
[
_Ty=std::pair<const int,std::unique_ptr<SomeInterface>>,
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Alloc=std::allocator<std::pair<const int,std::unique_ptr<SomeInterface>>>
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtree(1521) : see reference to function template instantiation 'std::_Tree_nod<_Traits>::_Node *std::_Tree_val<_Traits>::_Buynode<std::pair<_Ty1,_Ty2>&>(_Valty)' being compiled
with
[
_Traits=std::_Tmap_traits<int,std::unique_ptr<SomeInterface>,std::less<int>,std::allocator<std::pair<const int,std::unique_ptr<SomeInterface>>>,false>,
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Valty=std::pair<const int,std::unique_ptr<SomeInterface>> &
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtree(1516) : while compiling class template member function 'std::_Tree_nod<_Traits>::_Node *std::_Tree<_Traits>::_Copy(std::_Tree_nod<_Traits>::_Node *,std::_Tree_nod<_Traits>::_Node *)'
with
[
_Traits=std::_Tmap_traits<int,std::unique_ptr<SomeInterface>,std::less<int>,std::allocator<std::pair<const int,std::unique_ptr<SomeInterface>>>,false>
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\map(81) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<int,std::unique_ptr<SomeInterface>,std::less<int>,std::allocator<std::pair<const int,std::unique_ptr<SomeInterface>>>,false>
]
c:\projects\so\so\so.cpp(18) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
with
[
_Kty=int,
_Ty=std::unique_ptr<SomeInterface>
]
Run Code Online (Sandbox Code Playgroud)
Tim*_*imo 23
给出错误是因为编译器无法为ExportedClass创建复制构造函数和复制赋值运算符.这将需要复制unique_ptr对象,这些对象没有复制构造函数(它们是可移动的但不可复制).
对于普通类,没有给出错误,因为复制构造函数/赋值实际上并未在任何地方使用.但是当__declspec(dllexport)存在时,所有编译器生成的函数都会被实例化(不确定这里是否有正确的术语,但是类似于:).
解决错误的一种方法是为ExportedClass定义这两个函数并将它们标记为私有:
struct __declspec(dllexport) ExportedClass
{
std::map<int, std::unique_ptr<SomeInterface>> mData;
private:
ExportedClass(const ExportedClass&) {}
ExportedClass& operator=(const ExportedClass&) { return *this; }
};
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11603 次 |
最近记录: |