名前空間
変種
操作

std::remove, std::remove_if

提供: cppreference.com
< cpp‎ | algorithm
 
 
アルゴリズムライブラリ
実行ポリシー (C++17)
非変更シーケンス操作
(C++11)(C++11)(C++11)
(C++17)
変更シーケンス操作
removeremove_if
(C++17以前)

未初期化記憶域の操作
分割操作
ソート操作
(C++11)
二分探索操作
集合操作 (ソート済み範囲用)
ヒープ操作
(C++11)
最小/最大演算
(C++11)
(C++17)
順列
数値演算
C のライブラリ
 
ヘッダ <algorithm> で定義
(1)
template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
(C++20以前)
template< class ForwardIt, class T >
constexpr ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
(C++20およびそれ以降)
template< class ExecutionPolicy, class ForwardIt, class T >
ForwardIt remove( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, const T& value );
(2) (C++17およびそれ以降)
(3)
template< class ForwardIt, class UnaryPredicate >
ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPredicate p );
(C++20以前)
template< class ForwardIt, class UnaryPredicate >
constexpr ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPredicate p );
(C++20およびそれ以降)
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >
ForwardIt remove_if( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, UnaryPredicate p );
(4) (C++17およびそれ以降)

範囲 [first, last) から特定の基準を満たす要素をすべて削除し、その範囲の新しい終端を指すイテレータを返します。

1) value と等しい要素をすべて削除します。
3) 述語 ptrue を返す要素をすべて削除します。
2,4) (1,3) と同じですが、 policy に従って実行されます。 これらのオーバーロードは、 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> が true でなければ、オーバーロード解決に参加しません。

削除は、範囲の先頭に削除されない要素が現れるように、範囲内の要素をずらす (ムーブ代入によって) ことで行われます。 残る要素の相対順序は維持され、コンテナの物理的なサイズは変更されません。 新しい範囲の論理的な終端と物理的な終端の間の要素を指すイテレータは逆参照可能なままですが、要素それ自体は未規定の値 (MoveAssignable の事後条件の通りの) を持ちます。 remove の呼び出しには、一般的には、それらの未規定の値を消去し、新しい論理的なサイズに一致させるためにコンテナの物理的なサイズを減らす、コンテナの erase メンバ関数の呼び出しが続きます。

目次

[編集] 引数

first, last - 処理する要素の範囲
value - 削除する要素の値
policy - 使用する実行ポリシー。 詳細は実行ポリシーを参照してください
p - 要素が削除されるべき場合に ​true を返す単項述語。

述語関数のシグネチャは以下と同等なものであるべきです。

 bool pred(const Type &a);

シグネチャが const & を持つ必要はありませんが、関数は渡されたオブジェクトを変更してはなりません。
TypeForwardIt 型のオブジェクトの逆参照から暗黙に変換可能なものでなければなりません。 ​

型の要件
-
ForwardItForwardIterator の要件を満たさなければなりません。
-
ForwardIt を逆参照した型は MoveAssignable の要件を満たさなければなりません。
-
UnaryPredicatePredicate の要件を満たさなければなりません。

[編集] 戻り値

値の新しい範囲の終端イテレータ (これが end でない場合、それは未規定な値を指し、そのイテレータと end の間のあらゆる値を指すイテレータも未規定な値を指します)。

[編集] 計算量

ちょうど std::distance(first, last) 回の述語の適用。

[編集] 例外

テンプレート引数 ExecutionPolicy を持つオーバーロードは以下のようにエラーを報告します。

  • アルゴリズムの一部として呼び出された関数の実行が例外を投げ、 ExecutionPolicy が3つの標準のポリシーのいずれかの場合は、 std::terminate が呼ばれます。 それ以外のあらゆる ExecutionPolicy については、動作は処理系定義です。
  • アルゴリズムがメモリの確保に失敗した場合は、 std::bad_alloc が投げられます。

[編集] ノート

似た名前のコンテナのメンバ関数 list::removelist::remove_ifforward_list::remove および forward_list::remove_if は削除された要素を消去します。

これらのアルゴリズムは、 ForwardIt が MoveAssignable な型を逆参照できないため、 std::setstd::map のような連想コンテナで使用することはできません (これらのコンテナではキーが変更可能でありません)。

標準ライブラリは、ファイルを削除するために使用される、 const char* を取る std::remove のオーバーロード std::remove も定義しています。

std::removevalue を参照で取るため、それが範囲 [first, last) の要素を指す参照である場合は、予期しない動作をする可能性があります。

[編集] 実装例

1つめのバージョン
template< class ForwardIt, class T >
ForwardIt remove(ForwardIt first, ForwardIt last, const T& value)
{
    first = std::find(first, last, value);
    if (first != last)
        for(ForwardIt i = first; ++i != last; )
            if (!(*i == value))
                *first++ = std::move(*i);
    return first;
}
2つめのバージョン
template<class ForwardIt, class UnaryPredicate>
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
{
    first = std::find_if(first, last, p);
    if (first != last)
        for(ForwardIt i = first; ++i != last; )
            if (!p(*i))
                *first++ = std::move(*i);
    return first;
}

[編集]

以下のコードは、すべての非空白文字を左へずらすことによってすべての空白を削除し、その後、余分な部分を消去します。 これは erase-remove イディオムの例です。

#include <algorithm>
#include <string>
#include <iostream>
#include <cctype>
 
int main()
{
    std::string str1 = "Text with some   spaces";
    str1.erase(std::remove(str1.begin(), str1.end(), ' '),
               str1.end());
    std::cout << str1 << '\n';
 
    std::string str2 = "Text\n with\tsome \t  whitespaces\n\n";
    str2.erase(std::remove_if(str2.begin(), 
                              str2.end(),
                              [](unsigned char x){return std::isspace(x);}),
               str2.end());
    std::cout << str2 << '\n';
}

出力:

Textwithsomespaces
Textwithsomewhitespaces

[編集] 関連項目

指定範囲の要素から一定の基準を満たすものを除いてコピーします
(関数テンプレート) [edit]
指定範囲の連続している重複要素を削除します
(関数テンプレート) [edit]