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

履歴 編集

class template
<ranges>

std::ranges::cache_latest_view(C++26)

namespace std::ranges {
  template<input_range V>
    requires view<V>
  class cache_latest_view : public view_interface<cache_latest_view<V>> { …… }; // (1)

  namespace views {
    inline constexpr /*unspecified*/ cache_latest = /*unspecified*/;             // (2)
  }
}

概要

  • (1): 元のRangeの最後にアクセスした要素 (間接参照結果) をキャッシュするview
  • (2): cache_latest_viewを生成するRangeアダプタオブジェクト

views::transformviews::filterを組み合わせた場合、filterが条件判定のために要素を間接参照し、さらにfor文の本体で同じ要素を参照することにより、変換関数が2回呼び出される。cache_latestを間に挟むことで、間接参照の結果をキャッシュし、変換関数の重複呼び出しを回避できる。

v | std::views::transform(expensive) // 重い変換関数
  | std::views::cache_latest         // 変換結果をキャッシュ
  | std::views::filter(pred)

キャッシュ戦略は、元のRangeの参照型が参照型である場合はポインタを、非参照型 (prvalue) である場合は値そのものを保持する。

Rangeコンセプト

borrowed sized output input forward bidirectional random_access contiguous common viewable view
  • ※: Vsized_rangeのとき
  • イテレータと番兵の型が異なるためcommon_rangeではない
  • 内部状態としてキャッシュを持つためforward_range以上にはならない
  • キャッシュへのポインタを保持するためborrowed_rangeではない

テンプレートパラメータ制約

効果

  • (2): 式views::cache_latest(E)の効果はcache_latest_view(E)と等しい

メンバ関数

名前 説明 対応バージョン
(constructor) コンストラクタ C++26
base Vの参照を取得する C++26
begin 先頭を指すイテレータを取得する C++26
end 番兵を取得する C++26
size 要素数を取得する C++26

継承しているメンバ関数

名前 説明 対応バージョン
empty Rangeが空かどうかを判定する C++26
operator bool Rangeが空でないかどうかを判定する C++26
front 先頭要素への参照を取得する C++26

メンバ型

名前 説明 対応バージョン
iterator イテレータ型(説明専用) C++26
sentinel 番兵型(説明専用) C++26

推論補助

名前 説明 対応バージョン
(deduction_guide) クラステンプレートの推論補助 C++26

基本的な使い方

#include <ranges>
#include <print>
#include <vector>

int main()
{
  std::vector v = {1, 2, 3, 4, 5};

  for (auto x : v | std::views::cache_latest) {
    std::println("{}", x);
  }
}

出力

1
2
3
4
5

変換関数の重複呼び出しを抑える

views::transformで重い変換を行い、views::filterで絞り込む場合、filterが条件判定で要素を間接参照し、その後の処理で再度間接参照されるため、変換関数が要素ごとに複数回呼び出される。間にcache_latestを挟むことで、変換関数の呼び出しを各要素1回に抑えられる。

#include <ranges>
#include <print>
#include <vector>

int main()
{
  std::vector v = {1, 2, 3, 4, 5};

  int call_count = 0;
  auto square = [&](int x) { ++call_count; return x * x; };

  for (auto x : v | std::views::transform(square)
                  | std::views::cache_latest
                  | std::views::filter([](int n) { return n > 5; })) {
    std::println("{}", x);
  }
  std::println("call_count: {}", call_count);
}

出力

9
16
25
call_count: 5

バージョン

言語

  • C++26

処理系

関連項目

参照