std::adjacent_difference
提供: 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>
| ヘッダ <numeric> で定義
|
||
| (1) | ||
template< class InputIt, class OutputIt > OutputIt adjacent_difference( InputIt first, InputIt last, OutputIt d_first ); |
(C++20未満) | |
template< class InputIt, class OutputIt > constexpr OutputIt adjacent_difference( InputIt first, InputIt last, OutputIt d_first ); |
(C++20以上) | |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > ForwardIt2 adjacent_difference( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first ); |
(2) | (C++17以上) |
| (3) | ||
template< class InputIt, class OutputIt, class BinaryOperation > OutputIt adjacent_difference( InputIt first, InputIt last, OutputIt d_first, BinaryOperation op ); |
(C++20未満) | |
template< class InputIt, class OutputIt, class BinaryOperation > constexpr OutputIt adjacent_difference( InputIt first, InputIt last, OutputIt d_first, BinaryOperation op ); |
(C++20以上) | |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryOperation > ForwardIt2 adjacent_difference( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first, BinaryOperation op ); |
(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;
}
|
例
Run this code
#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
関連項目
| 指定範囲の要素の部分和を計算します (関数テンプレート) | |
| 指定範囲の要素を合計します (関数テンプレート) |