std::replace, std::replace_if
| ヘッダー <algorithm> で定義 |
||
| (1) | ||
template< class ForwardIt, class T > void replace( ForwardIt first, ForwardIt last, |
(C++20 以降 constexpr) (C++26まで) |
|
| template< class ForwardIt, class T = typename std::iterator_traits <ForwardIt>::value_type > |
(C++26以降) | |
| (2) | ||
| template< class ExecutionPolicy, class ForwardIt, class T > void replace( ExecutionPolicy&& policy, |
(C++17以降) (C++26まで) |
|
| template< class ExecutionPolicy, class ForwardIt, class T = typename std::iterator_traits |
(C++26以降) | |
| (3) | ||
template< class ForwardIt, class UnaryPred, class T > void replace_if( ForwardIt first, ForwardIt last, |
(C++20 以降 constexpr) (C++26まで) |
|
| template< class ForwardIt, class UnaryPred, class T = typename std::iterator_traits |
(C++26以降) | |
| (4) | ||
| template< class ExecutionPolicy, class ForwardIt, class UnaryPred, class T > |
(C++17以降) (C++26まで) |
|
| template< class ExecutionPolicy, class ForwardIt, class UnaryPred, |
(C++26以降) | |
範囲[first, last)のすべての要素を、指定された基準を満たす場合にnew_valueで置き換えます。
|
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> が true である。 |
(C++20まで) |
|
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> が true である。 |
(C++20以降) |
もし*first = new_valueが無効(C++20まで)new_valueがfirstに書き込み可能でない(C++20以降)、プログラムは不正形式となります。
目次 |
[編集] パラメータ
| first, last | - | 処理する要素の 範囲 を定義するイテレータのペア |
| old_value | - | 置き換える要素の値 |
| policy | - | 使用する 実行ポリシー |
| p | - | 要素の値が置き換えられるべき場合にtrueを返す単項述語。 式p(v)は、ForwardItの値型(場合によってはconst)である、値カテゴリに関係なく、あらゆる引数 |
| new_value | - | 置き換えに使用する値。 |
| 型要件 | ||
-ForwardIt は LegacyForwardIterator の要件を満たさなければなりません。 | ||
-UnaryPred は Predicate の要件を満たさなければなりません。 | ||
[編集] 計算量
std::distance(first, last) を N とする
[編集] 例外
ExecutionPolicy というテンプレートパラメータを持つオーバーロードは、次のようにエラーを報告します。
- アルゴリズムの一部として呼び出された関数の実行が例外をスローし、
ExecutionPolicyが 標準ポリシー のいずれかである場合、std::terminate が呼び出されます。その他のExecutionPolicyの場合、動作は実装定義です。 - アルゴリズムがメモリの割り当てに失敗した場合、std::bad_alloc がスローされます。
[編集] 注意
アルゴリズムはold_valueとnew_valueを参照で受け取るため、どちらかが範囲[first, last)の要素への参照である場合、予期しない動作が発生する可能性があります。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type |
202403 |
(C++26) | リスト初期化(バージョン 1-4) |
[編集] 実装例
| replace (1) |
|---|
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type> void replace(ForwardIt first, ForwardIt last, const T& old_value, const T& new_value) { for (; first != last; ++first) if (*first == old_value) *first = new_value; } |
| replace_if (3) |
template<class ForwardIt, class UnaryPred, class T = typename std::iterator_traits<ForwardIt>::value_type> void replace_if(ForwardIt first, ForwardIt last, UnaryPred p, const T& new_value) { for (; first != last; ++first) if (p(*first)) *first = new_value; } |
[編集] 例
#include <algorithm> #include <array> #include <complex> #include <functional> #include <iostream> void println(const auto& seq) { for (const auto& e : seq) std::cout << e << ' '; std::cout << '\n'; } int main() { std::array<int, 10> s{5, 7, 4, 2, 8, 6, 1, 9, 0, 3}; // Replace all occurrences of 8 with 88. std::replace(s.begin(), s.end(), 8, 88); println(s); // Replace all values less than 5 with 55. std::replace_if(s.begin(), s.end(), std::bind(std::less<int>(), std::placeholders::_1, 5), 55); println(s); std::array<std::complex<double>, 2> nums{{{1, 3}, {1, 3}}}; #ifdef __cpp_lib_algorithm_default_value_type std::replace(nums.begin(), nums.end(), {1, 3}, {4, 2}); #else std::replace(nums.begin(), nums.end(), std::complex<double>{1, 3}, std::complex<double>{4, 2}); #endif println(nums); }
出力
5 7 4 2 88 6 1 9 0 3 5 7 55 55 88 6 55 9 55 55 (4,2), (4,2)
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 283 | C++98 | TはCopyAssignable(およびreplaceの場合はEqualityComparable)である必要がありましたが、ForwardItの値型は常にTではなく、Tは常にForwardItに書き込めるわけではありませんでした。〜 〜 |
〜 〜 |
[編集] 関連項目
| 特定の基準を満たす要素を別の値に置き換えながら範囲をコピーする (関数テンプレート) | |
| (C++20)(C++20) |
特定の基準を満たすすべての値を別の値に置き換える (アルゴリズム関数オブジェクト) |