2011-12-07 98 views
11

鉴于std::vector<std::unique_ptr<SomeType> >,对其使用 remove_if是否合法?换句话说,鉴于此代码:你可以在`std :: unique_ptr`的容器上使用`std :: 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()); 

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

(我是,当然,假设条件不复制如果 条件具有类似特征:

struct Condition 
{ 
    bool operator()(std::unique_ptr<SomeType> ptr) const; 
}; 

,那么当然,所有的指针将是 后无效remove_if

+7

James Kanze提出问题 - 一个非常罕见的现象! – Nawaz

+3

'unique_ptr'不是可复制的,所以如果你使用了这个谓词,你的代码就不会编译。 – interjay

+1

为什么不呢? 'std :: unique'不可复制,但可移动。它可以移动到容器的末端。 –

回答

2

25.3.8在N3290谈到删除功能:

要求:类型的第一*应满足MoveAssignable 要求(表22)。

注:在范围[RET每个元素,最后一个),其中,RET的返回 值,具有有效的但unspeci音响ED状态下,由于算法可以 消除通过交换元件与原来在该范围内的元素相关或从其中移出 。

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

+0

§25.3.8/ 1是对目标类型的约束,而不是对'remove'的 实现。第25.3.8/6是我正在寻找的。太 不好,这是一个说明,而不是规范。但它的确意图清楚。 我应该在 之前阅读笔记,而不仅仅是规范文本。 +1无论如何,如果没有人发现更确切的东西,我会认为这是最终的回应。 –

+0

我有n3242。之后是否增加了§25.3.8/ 6?我的/ 6讨论了'remove_copy [_if]'。 – kennytm

+2

我相信这个笔记是不正确的。好的事情是不规范的。 ;-)算法不允许交换元素,因为元素不需要是可交换的。该算法只能使用移动分配。 –

5

就像erase()resize()remove_if()移动元素(可能通过交换),使容器中的元素并不需要可拷贝。 unique_ptr没有什么特别之处,它只是另一种移动类型。

正如你指出的那样,谓词当然应该由const-reference引用元素。再次,就像任何可移动的类型一样。

+0

标准中规定了哪些内容?更重要的是,它在哪里 指出'remove_if'不会移动到一些临时的,也许以后到 将值留在那里,因为它确定不需要在其他地方放置 ?容器和成员函数已被重新编写为 以反映移动语义,但我不知道在这方面描述'remove_if'的语言 有任何更改。 –

+1

@JamesKanze:§25.3.8/ 1? – kennytm

+0

@KennyTM:击败我吧,谢谢! –

相关问题