std::ranges::shift_left, std::ranges::shift_right
From cppreference.com
| ヘッダー <algorithm> で定義 |
||
| 呼び出しシグネチャ |
||
| template< std::permutable I, std::sentinel_for<I> S > constexpr ranges::subrange<I> |
(1) | (C++23から) |
| template< ranges::forward_range R > requires std::permutable<ranges::iterator_t<R>> |
(2) | (C++23から) |
| template< std::permutable I, std::sentinel_for<I> S > constexpr ranges::subrange<I> |
(3) | (C++23から) |
| template< ranges::forward_range R > requires std::permutable<ranges::iterator_t<R>> |
(4) | (C++23から) |
範囲 [first, last) または r 内の要素を n ポジションずらす。 [first, last) が有効な範囲でない場合、動作は未定義。
1) 要素を範囲の先頭方向にずらす。
- n == 0 || n >= last - first の場合、効果はない。
- n < 0 の場合、動作は未定義。
- そうでなければ、
[0,last - first - n)内の各整数iについて、元々 first + n + i にあった要素を first + i の位置に移動させる。移動は 0 から始まるiの昇順で行われる。
3) 要素を範囲の末尾方向にずらす。
- n == 0 || n >= last - first の場合、効果はない。
- n < 0 の場合、動作は未定義。
- そうでなければ、
[0,last - first - n)内の各整数iについて、元々 first + i にあった要素を first + n + i の位置に移動させる。Iがbidirectional_iteratorをモデル化している場合、移動は last - first - n - 1 から始まるiの降順で行われる。
元の範囲にはあったが新しい範囲にはない要素は、有効だが未指定の状態のまま残される。
このページで説明されている関数のようなエンティティは、アルゴリズム関数オブジェクト(非公式にはニーブロイドとして知られている)です。つまり、
- これらのいずれかを呼び出す際に、明示的なテンプレート引数リストを指定することはできません。
- これらのいずれも実引数依存の名前探索には見えません。
- これらのいずれかが関数呼び出し演算子の左側の名前として通常の非修飾名探索によって見つかった場合、実引数依存の名前探索は抑制されます。
目次 |
[編集] パラメータ
| first, last | - | シフトする要素の範囲を定義するイテレータと番兵のペア |
| r | - | シフトする要素の範囲 |
| n | - | シフトする位置の数 |
[編集] 戻り値
1,2) {first, /*NEW_LAST*/}。ここで
NEW_LAST は結果の範囲の末尾であり、以下と同等。- first + (last - first - n) (
nが last - first より小さい場合)。 - first (それ以外の場合)。
3,4) {/*NEW_FIRST*/, last}。ここで
NEW_FIRST は結果の範囲の先頭であり、以下と同等。- first + n (
nが last - first より小さい場合)。 - last (それ以外の場合)。
[編集] 計算量
1,2) 最大で ranges::distance(first, last) - n 回の代入。
3,4) 最大で ranges::distance(first, last) - n 回の代入またはスワップ。
[編集] 備考
I が bidirectional_iterator または (より良い) random_access_iterator をモデル化している場合、ranges::shift_left / ranges::shift_right は一般的な実装でより効率的である。
イテレータ型が contiguous_iterator をモデル化し、その値型のスワップが自明でない特殊メンバ関数も ADL で見つかった swap も呼び出さない場合、実装 (例: MSVC STL) はベクトル化を有効にできる。
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_shift |
202202L |
(C++23) | std::ranges::shift_left および std::ranges::shift_right |
[編集] 例
このコードを実行
#include <algorithm> #include <iostream> #include <string> #include <type_traits> #include <vector> struct S { int value{0}; bool specified_state{true}; S(int v = 0) : value{v} {} S(S const& rhs) = default; S(S&& rhs) { *this = std::move(rhs); } S& operator=(S const& rhs) = default; S& operator=(S&& rhs) { if (this != &rhs) { value = rhs.value; specified_state = rhs.specified_state; rhs.specified_state = false; } return *this; } }; template<typename T> std::ostream& operator<<(std::ostream& os, std::vector<T> const& v) { for (const auto& s : v) { if constexpr (std::is_same_v<T, S>) s.specified_state ? os << s.value << ' ' : os << ". "; else if constexpr (std::is_same_v<T, std::string>) os << (s.empty() ? "." : s) << ' '; else os << s << ' '; } return os; } int main() { std::cout << std::left; std::vector<S> a{1, 2, 3, 4, 5, 6, 7}; std::vector<int> b{1, 2, 3, 4, 5, 6, 7}; std::vector<std::string> c{"α", "β", "γ", "δ", "ε", "ζ", "η"}; std::cout << "vector<S> \tvector<int> \tvector<string>\n"; std::cout << a << " " << b << " " << c << '\n'; std::ranges::shift_left(a, 3); std::ranges::shift_left(b, 3); std::ranges::shift_left(c, 3); std::cout << a << " " << b << " " << c << '\n'; std::ranges::shift_right(a, 2); std::ranges::shift_right(b, 2); std::ranges::shift_right(c, 2); std::cout << a << " " << b << " " << c << '\n'; std::ranges::shift_left(a, 8); // has no effect: n >= last - first std::ranges::shift_left(b, 8); // ditto std::ranges::shift_left(c, 8); // ditto std::cout << a << " " << b << " " << c << '\n'; // std::ranges::shift_left(a, -3); // UB }
実行結果の例
vector<S> vector<int> vector<string> 1 2 3 4 5 6 7 1 2 3 4 5 6 7 α β γ δ ε ζ η 4 5 6 7 . . . 4 5 6 7 5 6 7 δ ε ζ η . . . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η .
[編集] 関連項目
| (C++20) |
要素の範囲を新しい場所にムーブする (アルゴリズム関数オブジェクト) |
| (C++20) |
要素の範囲を逆順で新しい場所にムーブする (アルゴリズム関数オブジェクト) |
| (C++20) |
範囲内の要素の順序を回転させる (アルゴリズム関数オブジェクト) |
| (C++20) |
範囲内の要素をシフトする (関数テンプレート) |