为什么使用std::auto_ptr<>
标准容器是错误的?
move
语义和unique_ptr
目的是为了避免与...有关的问题auto_ptr
。在C ++ 03中,由于auto_ptr
编译器和语言无法区分l和r值,因此该语言的功能不足以编写可在所有情况下正确安全运行的类,因此使用了一些“ hacks”来获得所需的行为。大多数时候。
为什么使用std::auto_ptr<>
标准容器是错误的?
move
语义和unique_ptr
目的是为了避免与...有关的问题auto_ptr
。在C ++ 03中,由于auto_ptr
编译器和语言无法区分l和r值,因此该语言的功能不足以编写可在所有情况下正确安全运行的类,因此使用了一些“ hacks”来获得所需的行为。大多数时候。
Answers:
C ++标准指出,STL元素必须是“可复制构造的”和“可分配的”。换句话说,必须能够分配或复制一个元素,并且这两个元素在逻辑上是独立的。std::auto_ptr
不满足此要求。
以下面的代码为例:
class X
{
};
std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);
std::auto_ptr<X> pX = vecX[0]; // vecX[0] is assigned NULL.
要克服此限制,如果没有C ++ 11 ,则应使用std::unique_ptr
,std::shared_ptr
或std::weak_ptr
智能指针或升压等效项。 这是这些智能指针的Boost库文档。
unique_ptr
还禁止复制,因此某些STL操作将无法正常运行,除非它们可以使用其移动语义。
std::unique_ptr
“:类模板只能由于移动语义而存在(其规范要求右值引用),因此从根本上要求C ++ 11。但是(和相关的)C ++ 11标准不再说STL元素类型必须是“可复制构造的”和“可分配的”。具有可移动性和可移动性就足够了。实际上,unique_ptr
实例只能是可移动构造的和可移动分配的。但是auto_ptr
实例也是如此!因此,在C ++ 11中,您可以使用auto_ptr
进行操作unique_ptr
。
reset
和release
需要的人
reset
和release
”,否则我的评论中看不到这有什么用。请注意这两个auto_ptr
和unique_ptr
具有这两种方法,和他们做同样的事情,在这两种情况下。
关于该主题的两篇超优秀文章:
auto_ptr
我敢肯定,如果某人某个时间来此线程并想学习和学习一些东西,那么这些链接将很有帮助。
sort()
比此处的所有答案都清晰。
STL容器存储所包含项目的副本。复制auto_ptr时,会将旧的ptr设置为null。这种行为破坏了许多容器方法。
unique_ptr
像任何适当的C ++ 11对象一样,@ Tracer 仅在移动构造或-assigned时才可以转移其资源的所有权,从而确保程序员必须故意传递一个std::move(sourceObject)
或临时值,而不是传递一个左值并以直觉/不可预测的方式对其进行突变副本分配...,这是这里的一个核心问题,在这里已得到充分强调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代码可能无法在本国际标准中进行编译。