はじめに
C++で、コンテナ(vector
など)の全要素をチェックして、「全ての要素が正の数か?」「少なくとも一つ偶数が含まれているか?」「負の数は一つも含まれていないか?」といった条件を判定したい場面はよくあります。
for
ループとif
文でこれらのロジックを自力で実装することもできますが、C++の標準ライブラリ <algorithm>
には、このような判定を行うための、意図が明確で便利な関数が用意されています。
all_of
: 全ての要素が条件を満たすかany_of
: いずれかの要素が条件を満たすかnone_of
: どの要素も条件を満たさないか
この記事では、これらの述語関数を使って、コンテナの要素を効率的に検証する方法を解説します。
【前提】C++11とは?
C++11(シーピープラスいちいち)は、2011年に正式化されたC++言語のメジャーアップデート版です。この記事で紹介する関数やラムダ式はC++11で導入されたため、利用するにはC++11以降に対応したコンパイラが必要です。
all_of
, any_of
, none_of
のサンプルコード
このコードは、vector
に格納された数値に対して、3つの異なる条件をそれぞれの関数で判定し、結果を出力します。
完成コード
#include <iostream>
#include <vector>
#include <algorithm> // all_of, any_of, none_of
using namespace std;
int main() {
vector<int> numbers = {10, 20, 35, 40};
// --- 1. all_of: 全ての要素が条件を満たすか ---
// 条件: 全ての要素は 0 より大きいか? (-> Yes)
if (all_of(numbers.begin(), numbers.end(), [](int n){ return n > 0; })) {
cout << "all_of: 全ての要素は正の数です。" << endl;
}
// --- 2. any_of: いずれかの要素が条件を満たすか ---
// 条件: 奇数の要素が一つでも含まれているか? (-> Yes, 35)
if (any_of(numbers.begin(), numbers.end(), [](int n){ return n % 2 != 0; })) {
cout << "any_of: 奇数の要素が含まれています。" << endl;
}
// --- 3. none_of: どの要素も条件を満たさないか ---
// 条件: 100 より大きい要素は一つもないか? (-> Yes)
if (none_of(numbers.begin(), numbers.end(), [](int n){ return n > 100; })) {
cout << "none_of: 100を超える要素はありません。" << endl;
}
return 0;
}
コードの解説
基本構文
3つの関数は、いずれも同じ形式の引数を取ります。 関数名(範囲の開始イテレータ, 範囲の終了イテレータ, 条件)
- 第1, 2引数: 判定したい要素の範囲をイテレータで指定します。
- 第3引数: 述語 (Predicate) と呼ばれる、条件を定義した関数(またはラムダ式)を渡します。この述語は、引数を一つ取り、
bool
値 (true
/false
) を返す必要があります。
ラムダ式 [](int n){ return ...; }
この部分はラムダ式と呼ばれ、その場で使える簡単な関数を定義しています。例えば [](int n){ return n > 0; }
は、「int
型のn
を受け取り、もしn
が0
より大きければtrue
を、そうでなければfalse
を返す」という条件を表す関数です。
各関数の動作
all_of
: 範囲内の全ての要素に対して述語を呼び出し、全てがtrue
を返した場合にのみ、all_of
自身もtrue
を返します。any_of
: 範囲内の要素に対して順番に述語を呼び出し、一つでもtrue
を返した時点で、any_of
はtrue
を返します(残りの要素はチェックしません)。none_of
: 範囲内の全ての要素に対して述語を呼び出し、全てがfalse
を返した場合にのみ、none_of
はtrue
を返します。
まとめ
今回は、C++の <algorithm>
ライブラリが提供する、コンテナの要素を検証するための述語関数を解説しました。
all_of
: 全員一致?any_of
: 誰かいる?none_of
: 誰もいない?
手動で for
ループを書いてフラグ管理をするよりも、これらの関数を使った方が、コードが簡潔になるだけでなく、「何をしているか」という意図が明確になり、バグの少ない堅牢なコードになります。