C++ 容器中的auto_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这样的纯移动类型是一等公民。这就是为什么移动语义对性能和正确性都有很大的改进。在绝大多数情况下,它们不再需要使

我知道auto_ptr破坏了复制语义,因此在容器中使用是不安全的,因为将一个auto_ptr复制到另一个auto_ptr将使source=NULL指针(这不就是移动语义吗??)。但同样,unique_ptr根本无法复制,只能转移所有权。那么,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
也提供了该通用算法的专用版本。无论如何,可移动类型是可交换的。