你能在'std :: unique_ptr`的容器上使用`std :: remove_if`吗?

Jam*_*nze 13 c++ c++11

鉴于std::vector<std::unique_ptr<SomeType> >,使用remove_if它是否合法 ?换句话说,给定此代码:

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() );
Run Code Online (Sandbox Code Playgroud)

在擦除后我保证所有指针仍然v有效.我知道,考虑到直观的实现 std::remove_if,并且考虑到我所看到的所有实现,它们将是.我想知道标准中是否有任何保证它的东西; 即,std::remove_if不允许复制任何有效条目而不将副本重新复制到其最终位置.

(当然,我认为条件不会复制.如果条件有如下签名:

struct Condition
{
    bool operator()( std::unique_ptr<SomeType> ptr ) const;
};
Run Code Online (Sandbox Code Playgroud)

当然,所有的指针都会在之后无效 remove_if.)

Ker*_* SB 5

就像erase()resize(),remove_if()移动元素(可能通过交换),因此容器元素不需要是可复制的.没什么特别的unique_ptr,它只是另一种移动类型.

正如您所指出的,谓词当然应该通过const-reference来获取元素.再次,就像任何可移动类型一样.


BЈо*_*вић 3

N3290 中的 25.3.8 谈到删除功能:

\n\n
\n

要求:*first 的类型应满足 MoveAssignable\n 要求(表 22)。

\n
\n\n

\n\n
\n

注意:[ret,last) 范围内的每个元素(其中 ret 是返回值)具有有效但未指定的\xef\xac\x81ed 状态,因为算法可以通过交换元素或从元素中移动来消除元素最初在该范围内。

\n
\n\n

这意味着它取决于您的谓词运算符。由于您的谓词不会创建副本,因此不会复制元素。

\n

  • 我认为该注释是不正确的。还好它不规范。;-) 该算法不允许交换元素,因为元素不需要可交换。该算法只能使用移动分配。 (2认同)