C++ 为什么不是';有没有std::remove的非破坏性版本?

C++ 为什么不是';有没有std::remove的非破坏性版本?,c++,c++-standard-library,C++,C++ Standard Library,一种算法,通过将元素移动到末端,不保留其顺序,同时保留未“移除”元素的顺序,以非破坏性方式“移除”范围内的元素,这种算法可能很有用,并且可以在线性时间内运行,无需辅助空间。实施很简单: template <typename ForwardIterator, typename UnaryPredicate> ForwardIterator nd_remove_if(ForwardIterator head, ForwardIterator last, UnaryPredicate pr

一种算法,通过将元素移动到末端,不保留其顺序,同时保留未“移除”元素的顺序,以非破坏性方式“移除”范围内的元素,这种算法可能很有用,并且可以在线性时间内运行,无需辅助空间。实施很简单:

template <typename ForwardIterator, typename UnaryPredicate>
ForwardIterator nd_remove_if(ForwardIterator head, ForwardIterator last, UnaryPredicate pred)
{
    using std::swap;

    ForwardIterator swap_head = head;
    while(head != last)
    {
        while(swap_head != last && !pred(*swap_head))
            ++swap_head;
        if(swap_head == last)
            break;

        if(!pred(*head))
            swap(*head, *swap_head);
        else
            ++swap_head;
        ++head;
    }
    return head;
}
模板
ForwardIterator nd_remove_if(ForwardIterator head、ForwardIterator last、一元谓词pred)
{
使用std::swap;
转发迭代器交换头=头;
while(头!=最后一个)
{
while(交换头!=最后一个和前一个(*交换头))
++交换头;
如果(交换头==最后一个)
打破
如果(!pred(*头))
交换(*交换头,*交换头);
其他的
++交换头;
++头部;
}
回流头;
}
基本上,它是一个对左侧稳定但对右侧不稳定的分区。与std::stable_partition相比,它的优势在于不要求右侧是稳定的,这样就可以在不需要额外空间的情况下实现线性时间


为什么这不在标准库中?我觉得它足够有用,足够通用,可以放在那里。

@NeilKirk我所说的非破坏性是指不将删除的值保留在未指定的状态,即它们保证与以前相同,只是在最后,不一定以相同的顺序。我说的有道理吗?出于好奇,如果
稳定的分区
删除
都不合适的话,你有什么用例?我怀疑它是非常具体的,如果考虑到它的话,这是它不是标准的一部分的主要原因,但是也许你的用例会比我想象的更一般。啊,是的,我想这是一个很好的例子。如果您需要保持顺序,您可以使用
稳定分区
,但当已知其中一个分区中的所有值都相等时,该分区所做的工作比需要的多。@mebob因此在我的注释中使用了“当[…]所做的工作比需要的多时除外”。)我同意你的结论,
stable_partition
不是这里的最佳方法。基本上,你想要的是一个版本的
std::remove
,它使用
swap
而不是复制或移动分配。如果查看,只需替换
*first++=std::move(*i)
交换(*first++,*i)(或者,使用iter_交换),您可以得到您想要的,在左边保留顺序,在右边保留有效对象(以相反的顺序..我猜您可以通过反转右边的范围来获得线性时间无额外空间稳定的分区)。我想这可能是标准算法的一部分。