名前空間
変種
操作

std::ranges::move_backward、std::ranges::move_backward_result

From cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとRangeアルゴリズム (C++20)
制約付きアルゴリズム、例: ranges::copy, ranges::sort, ...
実行ポリシー (C++17)
シーケンスを変更しない操作
一括操作
(C++17)
検索操作
(C++11)                (C++11)(C++11)

シーケンスを変更する操作
コピー操作
(C++11)
(C++11)
スワップ操作
変換操作
生成操作
削除操作
順序変更操作
(C++17まで)(C++11)
(C++20)(C++20)
サンプリング操作
(C++17)

ソートおよび関連操作
パーティション操作
ソート操作
二分探索操作
(パーティション化された範囲)
集合操作 (ソート済み範囲)
マージ操作 (ソート済み範囲)
ヒープ操作
最小/最大操作
(C++11)
(C++17)
辞書順比較操作
順列操作
Cライブラリ
数値演算
未初期化メモリに対する操作
 
制約付きアルゴリズム
このメニューのすべての名前は名前空間 `std::ranges` に属します
シーケンスを変更しない操作
シーケンスを変更する操作
パーティション操作
ソート操作
二分探索操作 (ソート済み範囲)
       
       
集合操作 (ソート済み範囲)
ヒープ操作
最小/最大操作
       
       
順列操作
畳み込み操作
数値演算
(C++23)            
未初期化ストレージに対する操作
戻り値の型
 
ヘッダー <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)` で定義された範囲の要素を、`N = ranges::distance(first, last)` となるような `[d_last - N, d_last)` の別の範囲に移動します。要素は逆順(最後の要素が最初に移動)に移動されますが、相対的な順序は保持されます。`d_last` が `(first, last]` の内側にある場合、動作は未定義です。そのような場合、代わりに `ranges::move` を使用することができます。
2) `(1)` と同様ですが、ソース範囲として `r` を使用します。これは `first` として `ranges::begin(r)`、`last` として `ranges::end(r)` を使用するのと同等です。

移動元範囲の要素は、移動前と同じ値であるとは限りませんが、適切な型の有効な値を含んだままになります。これは、各整数 `n` (`0 ≤ n < N`)に対して `*(d_last - n) = ranges::iter_move(last - n)` を使用するのと同等です。

このページで説明されている関数のようなエンティティは、アルゴリズム関数オブジェクト(非公式にはニーブロイドとして知られている)です。つまり、

目次

[編集] パラメータ

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 {};

[編集]

#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++11)
要素の範囲を新しい場所にムーブする
(関数テンプレート) [編集]
(C++11)
引数をxvalueに変換する
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)