std::adjacent_difference
ヘッダ <numeric> で定義 | ||
(1) | ||
template<class InputIt, class OutputIt > OutputIt adjacent_difference( InputIt first, InputIt last, | (C++20以前) | |
template<class InputIt, class OutputIt > constexpr OutputIt adjacent_difference( InputIt first, InputIt last, | (C++20およびそれ以降) | |
template<class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > ForwardIt2 adjacent_difference( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, | (2) | (C++17およびそれ以降) |
(3) | ||
template<class InputIt, class OutputIt, class BinaryOperation > OutputIt adjacent_difference( InputIt first, InputIt last, | (C++20以前) | |
template<class InputIt, class OutputIt, class BinaryOperation > constexpr OutputIt adjacent_difference( InputIt first, InputIt last, | (C++20およびそれ以降) | |
template<class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryOperation > ForwardIt2 adjacent_difference( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, | (4) | (C++17およびそれ以降) |
範囲 [first, last)
の隣接する要素それぞれの組の2つめと1つめの差を計算し、その結果を d_first + 1
から始まる範囲に書き込みます。 *first
のコピーが無変更で *d_first
に書き込まれます。
InputIt
の値型である累積変数 acc
を作成し、それを *first で初期化し、その結果を *d_first に代入します。 その後、 [first + 1, last)
内のすべてのイテレータ i
について、順番に、型が InputIt
の値型であるオブジェクト val
を作成し、それを *i で初期化し、 val - acc(C++20以前)val - std::move(acc)(C++20およびそれ以降) (オーバーロード (1)) または op(val, acc)(C++20以前)op(val, std::move(acc))(C++20およびそれ以降) (オーバーロード (3)) を計算し、その結果を *(d_first +(i - first)) に代入し、 val
から acc
にムーブ代入します。[1, last - first - 1]
内のすべての d
について、型が ForwardIt1 の値型であるオブジェクトを作成し、それを *(first + d)-*(first + d -1) (オーバーロード (2)) または op(*(first + d), *(first + d -1)) (オーバーロード (4)) で初期化し、その結果を *(d_first + d) に代入します。 これは policy
に従って実行されます。 このオーバーロードは、std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> が true である場合にのみ、オーバーロード解決に参加します。以下の操作と同等です。
*(d_first)=*first;*(d_first+1)=*(first+1)-*(first);*(d_first+2)=*(first+2)-*(first+1);*(d_first+3)=*(first+3)-*(first+2); ...
| (C++11以前) |
| (C++11およびそれ以降) |
目次 |
[編集]引数
first, last | - | 要素の範囲 |
d_first | - | 書き込む範囲の先頭 |
policy | - | 使用する実行ポリシー。 詳細は実行ポリシーを参照してください |
op | - | 適用される二項演算関数オブジェクト。 関数のシグネチャは以下と同等であるべきです。 Ret fun(const Type1 &a, const Type2 &b); シグネチャが const& を持つ必要はありません。 |
型の要件 | ||
-InputIt は InputIterator の要件を満たさなければなりません。 InputIt の値型は MoveAssignable でなければならず、 *first の型から構築可能でなければなりません。 | ||
-OutputIt は OutputIterator の要件を満たさなければなりません。 acc (累積値) と val - acc または op(val, acc)(C++20以前)val - std::move(acc) または op(val, std::move(acc))(C++20およびそれ以降) の結果はどちらも OutputIt に書き込み可能でなければなりません。 | ||
-ForwardIt1, ForwardIt2 は ForwardIterator の要件を満たさなければなりません。 ForwardIt1 の値型は CopyConstructible でなければならず、式 *first -*first または op(*first, *first) から構築可能でなければならず、 ForwardIt2 の値型に代入可能でなければなりません。 |
[編集]戻り値
最後に書き込まれた要素の次を指すイテレータ。
[編集]ノート
first == last
の場合、この関数は効果を持たず、単に d_first
を返します。
[編集]計算量
ちょうど (last - first) - 1
回の二項演算の適用。
[編集]例外
テンプレート引数 ExecutionPolicy
を持つオーバーロードは以下のようにエラーを報告します。
- アルゴリズムの一部として呼び出された関数の実行が例外を投げ、
ExecutionPolicy
が3つの標準のポリシーのいずれかの場合は、 std::terminate が呼ばれます。 それ以外のあらゆるExecutionPolicy
については、動作は処理系定義です。 - アルゴリズムがメモリの確保に失敗した場合は、 std::bad_alloc が投げられます。
[編集]実装例
1つめのバージョン |
---|
template<class InputIt, class OutputIt> OutputIt adjacent_difference(InputIt first, InputIt last, OutputIt d_first){if(first == last)return d_first; typedeftypenamestd::iterator_traits<InputIt>::value_type value_t; value_t acc =*first;*d_first = acc;while(++first != last){ value_t val =*first;*++d_first = val - std::move(acc);// std::move since C++20 acc = std::move(val);}return++d_first;} |
2つめのバージョン |
template<class InputIt, class OutputIt, class BinaryOperation> OutputIt adjacent_difference(InputIt first, InputIt last, OutputIt d_first, BinaryOperation op){if(first == last)return d_first; typedeftypenamestd::iterator_traits<InputIt>::value_type value_t; value_t acc =*first;*d_first = acc;while(++first != last){ value_t val =*first;*++d_first = op(val, std::move(acc));// std::move since C++20 acc = std::move(val);}return++d_first;} |
[編集]例
#include <numeric>#include <vector>#include <iostream>#include <functional> int main(){// Default implementation - the difference b/w two adjacent items std::vector<int> v{2, 4, 6, 8, 10, 12, 14, 16, 18, 20}; std::adjacent_difference(v.begin(), v.end(), v.begin()); for(auto n : v){std::cout<< n <<' ';}std::cout<<'\n'; // Fibonacci // Notice, next item on the list is the result of the current iteration v =std::vector<int>(10); v[0]=1; std::adjacent_difference(v.begin(), v.end()-1, v.begin()+1, std::plus<int>()); for(auto n : v){std::cout<< n <<' ';}std::cout<<'\n';}
出力:
2 2 2 2 2 2 2 2 2 2 1 1 2 3 5 8 13 21 34 55
[編集]関連項目
指定範囲の要素の部分和を計算します (関数テンプレート) | |
指定範囲の要素を合計します (関数テンプレート) |