为什么在标准容器中使用std::auto_ptr<>是错误的?
当前回答
c++ 03标准(ISO-IEC 14882-2003)在第20.4.5条第3段中说:
[…] 【注:[…] auto_ptr不满足标准库的CopyConstructible和Assignable要求 容器元素,从而实例化标准库容器 使用auto_ptr会导致未定义的行为。-结束注]
c++ 11标准(ISO-IEC 14882-2011)在附录D.10.1第3段中规定:
[…] 注意:[…auto_ptr实例满足 MoveConstructible和MoveAssignable,但不符合要求 CopyConstructible和CopyAssignable。-结束注]
c++ 14标准(ISO-IEC 14882-2014)在附录C.4.2中说明 附件D:兼容性特性:
更改:类模板auto_ptr、unary_function和binary_function,函数模板random_shuffle和 函数模板(及其返回类型)ptr_fun, mem_fun Mem_fun_ref, bind1st和bind2nd没有定义。 理由:被新功能取代。 对原有特性的影响:使用这些类模板和函数模板的有效c++ 2014代码可能无法在此编译 国际标准。
其他回答
c++ 03标准(ISO-IEC 14882-2003)在第20.4.5条第3段中说:
[…] 【注:[…] auto_ptr不满足标准库的CopyConstructible和Assignable要求 容器元素,从而实例化标准库容器 使用auto_ptr会导致未定义的行为。-结束注]
c++ 11标准(ISO-IEC 14882-2011)在附录D.10.1第3段中规定:
[…] 注意:[…auto_ptr实例满足 MoveConstructible和MoveAssignable,但不符合要求 CopyConstructible和CopyAssignable。-结束注]
c++ 14标准(ISO-IEC 14882-2014)在附录C.4.2中说明 附件D:兼容性特性:
更改:类模板auto_ptr、unary_function和binary_function,函数模板random_shuffle和 函数模板(及其返回类型)ptr_fun, mem_fun Mem_fun_ref, bind1st和bind2nd没有定义。 理由:被新功能取代。 对原有特性的影响:使用这些类模板和函数模板的有效c++ 2014代码可能无法在此编译 国际标准。
STL容器需要能够复制存储在其中的项,并且被设计为期望原始和副本是等效的。自动指针对象有一个完全不同的契约,通过复制创建所有权的转移。这意味着auto_ptr容器将根据使用情况表现出奇怪的行为。
在Effective STL (Scott Meyers)第8项中有关于可能出错的详细描述,在Effective c++ (Scott Meyers)第13项中也有不那么详细的描述。
STL容器存储包含项的副本。当复制auto_ptr时,它将旧的ptr设置为null。许多容器方法都被这种行为破坏了。
两篇关于这个主题的超级优秀的文章:
智能指针-什么,为什么,哪个? 本周大师第25名
auto_ptr的复制语义与容器不兼容。
具体来说,将一个auto_ptr复制到另一个auto_ptr并不会创建两个相等的对象,因为其中一个已经失去了指针的所有权。
更具体地说,复制auto_ptr会导致其中一个副本放弃指针。这些元素中哪一个仍然保留在容器中没有定义。因此,如果将auto_ptrs存储在容器中,可能会随机失去对指针的访问。
推荐文章
- Uint8_t不能用cout打印
- c++中不必要的花括号
- 如何反转一个c++向量?
- 如何开始开发Internet Explorer扩展?
- Std::auto_ptr改为Std::unique_ptr
- int的最大值
- c++中有最大数组长度限制吗?
- 什么是“参数依赖查找”(又名ADL,或“Koenig查找”)?
- 公共朋友交换成员函数
- 如何在Go中使用c++
- 自定义c++分配器的引人注目的例子?
- RAII和c++中的智能指针
- 如何构建和使用谷歌TensorFlow c++ api
- 断言是邪恶的吗?
- 下面这些短语在c++中是什么意思:0 -,default-和value-initialization?