我在构造不可复制的对象时遇到问题。让我们考虑以下示例:
class Uncopyable{
protected:
Uncopyable(){};
~Uncopyable(){};
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
class Base { };
class Derived : public Base { };
class A : private Uncopyable {
public:
A(std::map<std::string, std::shared_ptr<Base>> & inMap);
private:
A(const A&);
A& operator=(const A&);
};
int main() {
std::map<std::string, std::shared_ptr<Derived>> lMap;
std::shared_ptr<A> oA(std::make_shared<A>(lMap));
}
如果我假设我的对象A是不可复制的,那么它将无法正常工作。作为一个指针,我希望我的对象A能够理解Derived是一个Base,但是却收到以下消息:
error C2664: 'A::A(const A &)' : cannot convert argument 1 from 'std::map<std::string,std::shared_ptr<Derived>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<Base>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> &'
1> with
1> [
1> _Kty=std::string
1> , _Ty=std::shared_ptr<Derived>
1> ]
1> and
1> [
1> _Kty=std::string
1> , _Ty=std::shared_ptr<Base>
1> ]
谢谢。
该错误与A
的不可复制性无关,并且确实不在复制构造函数中-而是在map
构造函数中。该错误与以下事实有关:A'
构造函数采用
std::map<std::string, std::shared_ptr<Base>> &
并且您正在通过:
std::map<std::string, std::shared_ptr<Derived>>
作为类型的左值引用的参数T
只能由类型的左值T
或派生自T
(或带有的类型的operator T&
)左值来满足。但是std::map<std::string, std::shared_ptr<Derived>>
实际上并没有继承std::map<std::string, std::shared_ptr<Base>>
-两种类型也根本没有关联-没有的交叉类型构造函数std::map
。
换句话说,仅仅因为aD
是aB
并不意味着amap<X, D>
是a map<X, B>
。以这种方式,C ++类型系统中没有类型的协方差。某些类型至少可以让你构建一个Class<B>
从Class<D>
(例如std::shared_ptr
),但是这不是标准集装箱的真实(例如vector
,map
,...)
您必须更改lMap
为按住std::shared_ptr<Base>
s才能起作用。它可以在内部保留std::shared_ptr<Derived>
s-但map
类型必须匹配。
旁注,在C ++ 11中,您不需要Uncopyable
。您可以简单地显式地执行delete
这些操作:
A(A const& ) = delete;
A& operator=(A const& ) = delete;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句