std:: rotate
|
定義先ヘッダ
<algorithm>
|
||
|
template
<
class
ForwardIt
>
ForwardIt rotate ( ForwardIt first, ForwardIt middle, ForwardIt last ) ; |
(1) | (constexpr since C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt
>
ForwardIt rotate
(
ExecutionPolicy
&&
policy,
|
(2) | (since C++17) |
std::rotate
は範囲
[
first
,
last
)
内の要素を、
[
first
,
middle
)
の要素が
[
middle
,
last
)
の要素の後ろに配置されるように交換し、両方の範囲内の要素の順序は維持されます。
|
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,middle)または[middle,last)が 有効な範囲 ではありません。
|
(C++11以前) |
|
(C++11以降) |
目次 |
パラメータ
| first, last | - | 回転させる要素の 範囲 を定義するイテレータのペア |
| middle | - | 回転後の範囲の先頭に現れるべき要素 |
| policy | - | 使用する 実行ポリシー |
| 型要件 | ||
-
ForwardIt
は
LegacyForwardIterator
の要件を満たさなければならない。
|
||
戻り値
* first によって元々参照されていた要素へのイテレータ。すなわち、 std:: distance ( middle, last ) 番目の first の次のイテレータ。
計算量
最大で std:: distance ( first, last ) 回のスワップ。
例外
ExecutionPolicy
という名前のテンプレートパラメータを持つオーバーロードは、
以下のようにエラーを報告します:
-
アルゴリズムの一部として呼び出された関数の実行が例外をスローした場合、
ExecutionPolicyが 標準ポリシー のいずれかであるとき、 std::terminate が呼び出される。それ以外のExecutionPolicyについては、動作は実装定義である。 - アルゴリズムがメモリの確保に失敗した場合、 std::bad_alloc がスローされる。
実装例
実装例については libstdc++ 、 libc++ および MSVC STL も参照してください。
template<class ForwardIt> constexpr // C++20以降 ForwardIt rotate(ForwardIt first, ForwardIt middle, ForwardIt last) { if (first == middle) return last; if (middle == last) return first; ForwardIt write = first; ForwardIt next_read = first; // 「read」が「last」に達したときの読み取り位置 for (ForwardIt read = middle; read != last; ++write, ++read) { if (write == next_read) next_read = read; // 「first」が移動した位置を追跡 std::iter_swap(write, read); } // 残りのシーケンスを適切な位置に回転 rotate(write, next_read, last); return write; } |
注記
std::rotate
は、
ForwardIt
が
LegacyBidirectionalIterator
または(さらに良い場合)
LegacyRandomAccessIterator
を満たす場合、一般的な実装ではより高い効率性を発揮します。
実装(例:
MSVC STL
)は、イテレータ型が
LegacyContiguousIterator
を満たし、その値型の交換が非自明な特殊メンバ関数も
ADL
で見つかった
swap
も呼び出さない場合、ベクトル化を有効化することがあります。
例
std::rotate
は多くのアルゴリズムで共通して使用される構成要素です。この例では
挿入ソート
を実演しています。
#include <algorithm> #include <iostream> #include <vector> auto print = [](const auto remark, const auto& v) { std::cout << remark; for (auto n : v) std::cout << n << ' '; std::cout << '\n'; }; int main() { std::vector<int> v{2, 4, 2, 0, 5, 10, 7, 3, 7, 1}; print("before sort:\t\t", v); // insertion sort for (auto i = v.begin(); i != v.end(); ++i) std::rotate(std::upper_bound(v.begin(), i, *i), i, i + 1); print("after sort:\t\t", v); // simple rotation to the left std::rotate(v.begin(), v.begin() + 1, v.end()); print("simple rotate left:\t", v); // simple rotation to the right std::rotate(v.rbegin(), v.rbegin() + 1, v.rend()); print("simple rotate right:\t", v); }
出力:
before sort: 2 4 2 0 5 10 7 3 7 1 after sort: 0 1 2 2 3 4 5 7 7 10 simple rotate left: 1 2 2 3 4 5 7 7 10 0 simple rotate right: 0 1 2 2 3 4 5 7 7 10
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 488 | C++98 | first が指す要素の新しい位置が返されなかった | 返される |
関連項目
|
要素の範囲をコピーして回転する
(関数テンプレート) |
|
|
(C++20)
|
範囲内の要素の順序を回転する
(アルゴリズム関数オブジェクト) |