C++ 容器中的auto_ptr与unique_ptr;算法
我知道auto_ptr破坏了复制语义,因此在容器中使用是不安全的,因为将一个auto_ptr复制到另一个auto_ptr将使source=NULL指针(这不就是移动语义吗??)。但同样,unique_ptr根本无法复制,只能转移所有权。那么,unique_ptr在需要使用复制操作来复制和重新排列元素的容器和算法中如何使用?在绝大多数情况下,它们不再需要使用复制操作。像unique_ptr这样的纯移动类型是一等公民。这就是为什么移动语义对性能和正确性都有很大的改进。在绝大多数情况下,它们不再需要使用复制操作。像unique_ptr这样的纯移动类型是一等公民。这就是为什么移动语义在性能和正确性方面都有如此大的改进。有一个深入的解释,解释了为什么C++ 容器中的auto_ptr与unique_ptr;算法,c++,algorithm,c++11,containers,smart-pointers,C++,Algorithm,C++11,Containers,Smart Pointers,我知道auto_ptr破坏了复制语义,因此在容器中使用是不安全的,因为将一个auto_ptr复制到另一个auto_ptr将使source=NULL指针(这不就是移动语义吗??)。但同样,unique_ptr根本无法复制,只能转移所有权。那么,unique_ptr在需要使用复制操作来复制和重新排列元素的容器和算法中如何使用?在绝大多数情况下,它们不再需要使用复制操作。像unique_ptr这样的纯移动类型是一等公民。这就是为什么移动语义对性能和正确性都有很大的改进。在绝大多数情况下,它们不再需要使
自动\u ptr
是危险的,而唯一的\u ptr
不是:
主要论点是,在泛型代码中,具有副本语法的东西应该是副本,而不是移动:
template <class It>
void sort(It first, It last)
{
// ...
value_type pivot_element = *mid_point;
// ...
}
模板
无效排序(先排序,后排序)
{
// ...
值\类型轴\元素=*中点;
// ...
}
在上面的示例中,通用代码很可能具有这样的逻辑,即在所示的副本构造之后,pivot\u元素
和*mid\u point
必须等效。这可能是也可能不是std::lib
中的通用代码。它可能是您编写的通用代码
当value\u type
被证明是std::auto\u ptr
时,上面的代码会编译,但是pivot\u元素==*中点
的假设失败。随后出现运行时错误
当value\u type
被证明是std::unique\u ptr
时,上述代码在编译时失败(因为您无法复制std::unique\u ptr
)。因此,优先使用std::unique_ptr
而不是std::auto_ptr
可以有效地将运行时错误转换为编译时错误
现在,在std::lib
中,像sort
这样的算法也被重新指定,这样它们就不允许复制value\u type
。因此,现在(使用std::sort
)对auto_ptr
序列进行排序实际上是安全的。但是std::unique_ptr
完全取代了auto_ptr
的功能,并且auto_ptr
在使用复制的通用代码中使用仍然是危险的(unique_ptr
在此类通用代码中使用时无法编译)
因此,使用
unique_ptr
比使用auto_ptr
更安全,因为它在与复制的通用代码一起使用时拒绝编译。有一个深入的解释,解释了为什么auto_ptr
是危险的,而unique_ptr
不是:
主要论点是,在泛型代码中,具有副本语法的东西应该是副本,而不是移动:
template <class It>
void sort(It first, It last)
{
// ...
value_type pivot_element = *mid_point;
// ...
}
模板
无效排序(先排序,后排序)
{
// ...
值\类型轴\元素=*中点;
// ...
}
在上面的示例中,通用代码很可能具有这样的逻辑,即在所示的副本构造之后,pivot\u元素
和*mid\u point
必须等效。这可能是也可能不是std::lib
中的通用代码。它可能是您编写的通用代码
当value\u type
被证明是std::auto\u ptr
时,上面的代码会编译,但是pivot\u元素==*中点
的假设失败。随后出现运行时错误
当value\u type
被证明是std::unique\u ptr
时,上述代码在编译时失败(因为您无法复制std::unique\u ptr
)。因此,优先使用std::unique_ptr
而不是std::auto_ptr
可以有效地将运行时错误转换为编译时错误
现在,在std::lib
中,像sort
这样的算法也被重新指定,这样它们就不允许复制value\u type
。因此,现在(使用std::sort
)对auto_ptr
序列进行排序实际上是安全的。但是std::unique_ptr
完全取代了auto_ptr
的功能,并且auto_ptr
在使用复制的通用代码中使用仍然是危险的(unique_ptr
在此类通用代码中使用时无法编译)
因此,使用
unique_ptr
比使用auto_ptr
更安全,因为当与复制的通用代码一起使用时,它拒绝编译。“unique_ptr在需要使用复制操作的容器和算法中如何可用”一点也没有。但同样,许多操作不需要复制。可以通过swap
(和移动)进行重新安排。因此,swap使用移动语义?新的标准库通用交换基于移动构造和两个移动分配。但是unique\u ptr
也提供了该通用算法的专用版本。在任何情况下,可移动类型都是可交换的。“如何在需要使用复制操作的容器和算法中使用unique_ptr”一点也不重要。但同样,许多操作不需要复制。可以通过swap
(和移动)进行重新安排。因此,swap使用移动语义?新的标准库通用交换基于移动构造和两个移动分配。但是unique\u ptr
也提供了该通用算法的专用版本。无论如何,可移动类型是可交换的。