最終更新日時(UTC):
が更新

履歴 編集

function template
<algorithm>

std::ranges::move_backward(C++20)

namespace std::ranges {
  template <bidirectional_iterator I1,
            sentinel_for<I1> S1,
            bidirectional_iterator I2>
    requires indirectly_movable<I1, I2>
  constexpr move_backward_result<I1, I2>
    move_backward(I1 first,
                  S1 last,
                  I2 result);           // (1) C++20

  template <bidirectional_range R,
            bidirectional_iterator I>
    requires indirectly_movable<iterator_t<R>, I>
  constexpr move_backward_result<borrowed_iterator_t<R>, I>
    move_backward(R&& r,
                  I result);            // (2) C++20

  template <execution-policy Ep,
            random_access_iterator I1,
            sized_sentinel_for<I1> S1,
            random_access_iterator I2>
    requires indirectly_movable<I1, I2>
  move_backward_result<I1, I2>
    move_backward(Ep&& exec,
                  I1 first,
                  S1 last,
                  I2 result);           // (3) C++26

  template <execution-policy Ep,
            sized-random-access-range R,
            random_access_iterator I>
    requires indirectly_movable<iterator_t<R>, I>
  move_backward_result<borrowed_iterator_t<R>, I>
    move_backward(Ep&& exec,
                  R&& r,
                  I result);            // (4) C++26
}

概要

指定された範囲の要素を後ろからムーブする。

  • (1): イテレータ範囲を指定する
  • (2): Rangeを直接指定する
  • (3): (1)の並列アルゴリズム版。実行ポリシーを指定する
  • (4): (2)の並列アルゴリズム版。実行ポリシーを指定する

事前条件

result(first,last] の範囲に含まれてはならない。

効果

[first,last) 内にある要素を、それぞれ [result - (last-first),result) へムーブする。

ムーブは last - 1 から順番に行い、1 以上 last - first 以下であるそれぞれの n について、*(result - n) = std::move(*(last - n)) を行う。

戻り値

move_backward_result {
  .in  = last,
  .out = result - (last - first),
}

計算量

正確に last - first 回ムーブ代入が行われる。

備考

last[result - (last-first),result) の範囲内にあるときには、move() の代わりに move_backward() を使うべきである。

基本的な使い方

#include <algorithm>
#include <iostream>
#include <vector>
#include <memory>
#include <ranges>

void print(const std::unique_ptr<int>& v) {
  if (v) std::cout << *v       << std::endl;
  else   std::cout << "(null)" << std::endl;
}

int main() {
  std::vector<std::unique_ptr<int>> v;

  for (int i = 0; i < 5; i++) {
    v.emplace_back(new int(i));
  }

  // 0,1,2 の値がある範囲を、2,3,4 の値がある範囲へムーブする
  std::ranges::move_backward(v | std::views::take(3), v.end());

  // 以下のコードだと期待した結果にならないことを確認しよう。
  // 移動元の後方と移動先の前方で範囲が重なっている場合は、move_backwardを使わないといけない
  // std::ranges::move(v | std::views::take(3), v.begin() + 2);

  std::ranges::for_each(v, &print);
}

出力

(null)
(null)
0
1
2

並列アルゴリズムの例 (C++26)

#include <algorithm>
#include <execution>
#include <iostream>
#include <vector>

int main() {
  std::vector<int> v = {1, 2, 3, 0, 0};

  // 並列に先頭3要素を後方へムーブ
  std::ranges::move_backward(std::execution::par,
                             v.begin(), v.begin() + 3, v.end());

  for (int x : v) {
    std::cout << x << ' ';
  }
  std::cout << std::endl;
}

出力

1 2 1 2 3

バージョン

言語

  • C++20

処理系

参照