std::adjacent_difference - cppreference.com
提供: cppreference.com
<tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody>
| ヘッダ |
||
| (1) | ||
|
|
(C++20未満) | |
|
|
(C++20以上) | |
|
|
(2) | (C++17以上) |
| (3) | ||
|
|
(C++20未満) | |
|
|
(C++20以上) | |
|
|
(4) | (C++17以上) |
範囲 [first, last) の隣接する要素それぞれの組の2つめと1つめの差を計算し、その結果を d_first + 1 から始まる範囲に書き込みます。 *first のコピーが無変更で *d_first に書き込まれます。
1,3) まず、型が 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 にムーブ代入します。
first は d_first と等しくても構いません。
2,4) まず、型が ForwardIt1 の値型であるオブジェクトを作成し、それを *first で初期化し、その結果を *d_first に代入します。 その後、 [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 | - | 適用される二項演算関数オブジェクト。
関数のシグネチャは以下と同等であるべきです。
シグネチャが |
| 型の要件 | ||
-InputIt は LegacyInputIterator の要件を満たさなければなりません。 InputIt の値型は MoveAssignable でなければならず、 *first の型から構築可能でなければなりません。
| ||
-OutputIt は LegacyOutputIterator の要件を満たさなければなりません。 acc (累積値) と val - acc または op(val, acc) (C++20未満)val - std::move(acc) または op(val, std::move(acc)) (C++20以上) の結果はどちらも OutputIt に書き込み可能でなければなりません。
| ||
-ForwardIt1, ForwardIt2 は LegacyForwardIterator の要件を満たさなければなりません。 ForwardIt1 の値型は CopyConstructible でなければならず、式 *first - *first または op(*first, *first) から構築可能でなければならず、 ForwardIt2 の値型に代入可能でなければなりません。
| ||
戻り値
書き込まれた最後の要素の次の要素を指すイテレータ。
ノート
first == last の場合、この関数は効果を持たず、単に d_first を返します。
計算量
ちょうど (last - first) - 1 回の二項演算の適用。
例外
テンプレート引数 ExecutionPolicy を持つオーバーロードは以下のようにエラーを報告します。
- アルゴリズムの一部として呼び出された関数の実行が例外を投げ、
ExecutionPolicyが標準のポリシーのいずれかの場合は、 std::terminate が呼ばれます。 それ以外のあらゆるExecutionPolicyについては、動作は処理系定義です。 - アルゴリズムがメモリの確保に失敗した場合は、 std::bad_alloc が投げられます。
実装例
| 1つめのバージョン |
|---|
template<class InputIt, class OutputIt> constexpr // since C++20 OutputIt adjacent_difference(InputIt first, InputIt last, OutputIt d_first) { if (first == last) return d_first; typedef typename std::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> constexpr // since C++20 OutputIt adjacent_difference(InputIt first, InputIt last, OutputIt d_first, BinaryOperation op) { if (first == last) return d_first; typedef typename std::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 <array> #include <iostream> #include <functional> #include <iterator> int main() { // デフォルトの実装 - 2つの隣接する項目間の差 std::vector 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'; // フィボナッチ std::array<int, 10> a {1}; adjacent_difference(begin(a), std::prev(end(a)), std::next(begin(a)), std::plus<> {}); copy(begin(a), end(a), std::ostream_iterator<int> {std::cout, " "}); }
出力:
2 2 2 2 2 2 2 2 2 2 1 1 2 3 5 8 13 21 34 55