std::ranges::move_backward, std::ranges::move_backward_result
ja.cppreference.net から
| ヘッダ <algorithm>
|
||
| で定義呼び出しシグネチャ |
||
template< std::bidirectional_iterator I1, std::sentinel_for<I1> S1,
std::bidirectional_iterator I2 >
requires std::indirectly_movable<I1, I2>
constexpr move_backward_result<I1, I2>
move_backward( I1 first, S1 last, I2 d_last );
|
(1) | (C++20以上) |
template< ranges::bidirectional_range R, std::bidirectional_iterator I >
requires std::indirectly_movable<ranges::iterator_t<R>, I>
constexpr move_backward_result<ranges::borrowed_iterator_t<R>, I>
move_backward( R&& r, I d_last );
|
(2) | (C++20以上) |
| ヘルパ型 |
||
template< class I, class O >
using move_backward_result = ranges::in_out_result<I, O>;
|
(3) | (C++20以上) |
1)
[first, last) で定義された範囲の要素を、別の範囲 [d_last - N, d_last) に移動します。ただし、N = ranges::distance(first, last) です。要素は逆順で移動されます(最後の要素が最初に移動されます)が、それらの相対的な順序は保持されます。d_last が (first, last] 内にある場合の動作は未定義です。そのような場合、代わりに ranges::move を使用できます。2) (1) と同じですが、ソース範囲として
r を使用します。あたかも ranges::begin(r) を first として、ranges::end(r) を last として使用するかのようです。moved-from 範囲の要素は、適切な型の有効な値を引き続き保持しますが、移動前と同じ値であるとは限りません。あたかも *(d_last - n) = ranges::iter_move(last - n) を各整数 n に対して使用したかのようです。ただし、0 ≤ n < N です。
このページで説明されている関数のようなエンティティは、アルゴリズム関数オブジェクト (非公式に niebloid として知られている) です。すなわち:
- それらのいずれかを呼び出す際に、明示的なテンプレート引数リストを指定することはできません。
- それらはいずれも argument-dependent lookup からは見えません。
- それらのいずれかが 通常の非修飾名検索 によって関数呼び出し演算子の左側の名前として見つかった場合、argument-dependent lookup は抑制されます。
パラメータ
| first, last | - | 移動する要素の 範囲 を定義するイテレータ-センチネルペア |
| r | - | 移動する要素の範囲 |
| d_last | - | 宛先範囲の終端 |
戻り値
{ last, d_last - N } .
計算量
1)
正確に
N
回のムーブ代入。
2)
正確に
ranges::
distance
(
r
)
回のムーブ代入。
注記
重複する範囲を移動する場合、 ranges::move は左方向への移動(移動先範囲の先頭が元の範囲の外側にある場合)に適しており、 ranges::move_backward は右方向への移動(移動先範囲の終端が元の範囲の外側にある場合)に適しています。
実装例
struct move_backward_fn { template<std::bidirectional_iterator I1, std::sentinel_for<I1> S1, std::bidirectional_iterator I2> requires std::indirectly_movable<I1, I2> constexpr ranges::move_backward_result<I1, I2> operator()(I1 first, S1 last, I2 d_last) const { auto i {last}; for (; i != first; *--d_last = ranges::iter_move(--i)) {} return {std::move(last), std::move(d_last)}; } template<ranges::bidirectional_range R, std::bidirectional_iterator I> requires std::indirectly_movable<ranges::iterator_t<R>, I> constexpr ranges::move_backward_result<ranges::borrowed_iterator_t<R>, I> operator()(R&& r, I d_last) const { return (*this)(ranges::begin(r), ranges::end(r), std::move(d_last)); } }; inline constexpr move_backward_fn move_backward {}; |
`タグ内のC++コードは一切翻訳していません - C++固有の用語(`struct`, `template`, `constexpr`, `operator()`など)はそのまま保持しています - コードの構造とフォーマットは完全に維持されています - プロフェッショナルで正確な翻訳を心がけました
例
このコードを実行
#include <algorithm> #include <iostream> #include <string> #include <string_view> #include <vector> using Vec = std::vector<std::string>; void print(std::string_view rem, Vec const& vec) { std::cout << rem << "[" << vec.size() << "]: "; for (const std::string& s : vec) std::cout << (s.size() ? s : std::string{"·"}) << ' '; std::cout << '\n'; } int main() { Vec a{"▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"}; Vec b(a.size()); print("Before move:\n" "a", a); print("b", b); std::ranges::move_backward(a, b.end()); print("\n" "Move a >> b:\n" "a", a); print("b", b); std::ranges::move_backward(b.begin(), b.end(), a.end()); print("\n" "Move b >> a:\n" "a", a); print("b", b); std::ranges::move_backward(a.begin(), a.begin()+3, a.end()); print("\n" "Overlapping move a[0, 3) >> a[5, 8):\n" "a", a); }
出力例:
Before move: a[8]: ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ b[8]: · · · · · · · · Move a >> b: a[8]: · · · · · · · · b[8]: ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ Move b >> a: a[8]: ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ b[8]: · · · · · · · · Overlapping move a[0, 3) >> a[5, 8): a[8]: · · · ▄ ▅ ▁ ▂ ▃
関連項目
(C++20) |
要素の範囲を新しい位置に移動する (アルゴリズム関数オブジェクト) |
(C++20)(C++20) |
要素の範囲を新しい位置にコピーする (アルゴリズム関数オブジェクト) |
(C++20) |
要素の範囲を逆順にコピーする (アルゴリズム関数オブジェクト) |
(C++11) |
要素の範囲を新しい位置に移動する (関数テンプレート & アルゴリズム関数オブジェクト) |
(C++20) |
|
(C++11) |
引数をxvalueに変換する (関数テンプレート) |