【C++】Rangesライブラリ入門 | take, drop, filterで要素を抽出する方法

目次

はじめに

C++で、コンテナ(vectorなど)から「最初の3要素だけ」や「偶数の要素だけ」を取り出したい場合、従来は手動でforループとif文を組み合わせる必要がありました。

C++20で導入されたRanges(レンジ)ライブラリは、このようなデータシーケンスの操作を劇的に簡潔にするための強力なツールです。レンジアダプタ(views)をパイプ演算子(|)で繋げることで、まるでデータの流れを加工していくかのように、目的の要素を抽出できます。

この記事では、Rangesライブラリの中でも特に使用頻度の高い、以下の3つの基本的なレンジアダプタの使い方を解説します。

  • views::take: 先頭から指定した数の要素を抜き出す。
  • views::drop: 先頭から指定した数の要素を読み飛ばす。
  • views::filter: 条件に一致する要素だけを抜き出す。

【前提】C++20とは?

C++20(シーピープラスにーぜろ)は、2020年に正式化されたC++言語のメジャーアップデート版です。RangesライブラリはこのC++20で導入された主要機能のため、利用するにはC++20に対応したコンパイラが必要です。


レンジアダプタを使ったサンプルコード

このコードは、一つのvectorに対して、take, drop, filter の3つの異なるビューを適用し、それぞれの結果を出力します。

完成コード

#include <iostream>
#include <vector>
#include <ranges> // Rangesライブラリを使うために必要

namespace views = std::ranges::views; // views名前空間のエイリアス

int main() {
    std::vector<int> numbers = {10, 25, 30, 45, 50, 65, 70, 85, 90};

    // 1. views::take : 先頭から4つの要素を抜き出す
    std::cout << "先頭4要素 (take): ";
    for (int n : numbers | views::take(4)) {
        std::cout << n << " ";
    }
    std::cout << std::endl;

    // 2. views::drop : 先頭5つの要素を読み飛ばし、残りを抜き出す
    std::cout << "先頭5要素を飛ばす (drop): ";
    for (int n : numbers | views::drop(5)) {
        std::cout << n << " ";
    }
    std::cout << std::endl;

    // 3. views::filter : 条件(10の倍数)に一致する要素だけを抜き出す
    std::cout << "10の倍数のみ (filter): ";
    auto is_multiple_of_10 = [](int n) { return n % 10 == 0; };
    for (int n : numbers | views::filter(is_multiple_of_10)) {
        std::cout << n << " ";
    }
    std::cout << std::endl;

    return 0;
}

実行結果

先頭4要素 (take): 10 25 30 45 
先頭5要素を飛ばす (drop): 65 70 85 90 
10の倍数のみ (filter): 10 30 50 70 90 

コードの解説

| パイプ演算子

numbers | views::take(4) のように、コンテナとレンジアダプタを |(パイプ)で繋ぎます。これは、「numbers というデータの流れを、views::take(4) というフィルターに通す」というイメージです。

1. views::take(n)

元のコンテナの先頭から nの要素だけを含むビューを作成します。

2. views::drop(n)

元のコンテナの先頭から nの要素を無視し、それ以降の全ての要素を含むビューを作成します。

3. views::filter(条件)

引数として渡された条件を満たす (trueを返す) 要素だけを含むビューを作成します。

  • auto is_multiple_of_10 = [](int n) { return n % 10 == 0; };: この部分はラムダ式と呼ばれ、その場で使える簡単な関数を定義しています。「int型のnを受け取り、n10で割り切れればtrueを返す」という条件を表します。

ビューの特性:遅延評価

views は「ビュー(眺め)」という名前の通り、元のコンテナのデータをコピーしませんviews::take(4) は、元の numbers を「先頭4つだけ眺める」という設定を作成するだけで、実際にデータにアクセスするのは for ループが始まったときです。この「遅延評価」という仕組みにより、Rangesライブラリは非常に効率的に動作します。


まとめ

今回は、C++20のRangesライブラリを使って、コンテナから特定の要素を抽出する3つの基本的なアダプタを解説しました。

  • views::take: 先頭からN個
  • views::drop: 先頭N個を飛ばして、残り全部
  • views::filter: 条件に合うものだけ

Rangesライブラリは、これらのアダプタを | で繋げて、numbers | views::filter(...) | views::take(3) のように、複数の操作を組み合わせることも可能です。これにより、複雑なデータ操作を、宣言的で非常に読みやすいコードで記述することができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次