C++ 在“std::unique\u ptr”容器上是否可以使用“std::remove\u if”?

C++ 在“std::unique\u ptr”容器上是否可以使用“std::remove\u if”?,c++,c++11,C++,C++11,给定一个std::vector,使用它合法吗 是否在其上删除?换言之,鉴于此代码: std::vector<std::unique_ptr<SomeType> > v; // fill v, all entries point to a valid instance of SomeType... v.erase( std::remove_if( v.begin(), v.end(), someCondition ), v.end() ); ,则所有指针在 remove

给定一个
std::vector
,使用它合法吗
是否在其上删除?换言之,鉴于此代码:

std::vector<std::unique_ptr<SomeType> > v;
//  fill v, all entries point to a valid instance of SomeType...
v.erase( std::remove_if( v.begin(), v.end(), someCondition ), v.end() );
,则所有指针在
remove\u if

就像
erase()
resize()
一样,
remove\u if()
将移动元素(可能通过交换),因此容器元素不需要可复制。
unique\u ptr
没有什么特别之处,它只是另一种只移动的类型


正如您所指出的,谓词当然应该通过常量引用获取元素。同样,与任何可移动类型一样。

N3290中的25.3.8讲述了删除功能:

要求:第一个*的类型应满足可移动和可分配的 所需资源(表22)

注意:范围[ret,last]中的每个元素,其中ret是返回的 值具有有效但未指定的状态,因为算法可以 通过与已删除的图元交换或从中移动图元来删除图元 原来在这个范围内


这意味着它取决于谓词运算符。因为谓词不创建副本,那么元素就不会被复制。

James Kanze提问-一种非常罕见的现象!
unique\u ptr
是不可复制的,所以如果使用该谓词,代码将无法编译。为什么不呢?
std::unique
是不可复制,但可移动。它可以移动到容器的末尾。@KennyTM:但问题中给出的谓词按值获取参数,因此需要一个复制构造函数。@VJovic:不,他没有。他将该谓词作为一个复制谓词的示例。然后,他对指针无效做出了错误的陈述,这将是正确的ith
auto_ptr
但不是
unique_ptr
(代码根本无法编译).这在标准中有何规定?更重要的是,如果
没有移动到某个临时位置,可能以后会将值保留在那里,因为它确定不需要将其放在其他位置?容器和there成员函数已重新编写以反映移动语义,但我不知道在这方面,描述
remove\u的语言中的任何更改。@JamesKanze:注意,“remove”元素的状态是未指定的。最晚在您删除尾部序列或重新分配其中的元素时,指针将被释放,但可能会更早(即标准没有说明)@KerrekSB“已移除”的状态元素并不是我所担心的。它是未被删除的元素的状态。假设
remove\u如果
在移动元素之前准备了元素的一个副本,然后决定它不必被移动。@JamesKanze:它不会这样做。它只会移动元素。如果你没有副本构造函数和move constructor不是
noexcept
,那么它甚至不会编译,我认为,或者至少你必须冒着异常的风险。(这是17.6.3.5:分配器要求中的内容。)Pr.25.3.8/1是对目标类型的约束,而不是对<代码> Rebug < /C>的执行。{25.3.8/6是我所要查找的。太糟糕了,它是一个注释,而不是规范的。但是它确实使意图清晰。在发布之前,我应该已经阅读了注释,而不仅仅是规范文本。+ 1,我将把它视为最终响应。如果没有人发现更明确的内容。我有n3242。之后是否添加了§25.3.8/6?My/6讨论了
删除副本[\u if]
。我认为该注释不正确。幸好它不规范。-)该算法不允许交换元素,因为元素不需要可交换。该算法只能使用移动赋值。
struct Condition
{
    bool operator()( std::unique_ptr<SomeType> ptr ) const;
};