最終更新日時: 2025年07月09日 00時33分39秒 (JST)
Akira Takahashi が更新

履歴 編集

concept
<concepts>

# std::predicate(C++20)

    namespace std {
      template<class F, class... Args>
      concept predicate =
        regular_invocable<F, Args...> && boolean-testable<invoke_result_t<F, Args...>>;
    }

## 概要

`predicate`は、任意の関数呼び出し可能な型`F`が引数`Args...`によって関数呼び出し可能（`regular_invocable`）であり、その戻り値型が`bool`に変換可能であることを表すコンセプトである。

`predicate`のモデルとなる`F`はその引数`Args...`に対しての述語（predicate）と呼ばれ、（`<algorithm>`の関数などにおいて）引数がある条件を満たしているかを判定するものとして利用される。

## 例

    #include <iostream>
    #include <concepts>
    #include <random>

    template<typename F, typename... Args>
    requires std::predicate<F, Args...>
    void f(const char* name) {
      std::cout << name << " is predicate" << std::endl;
    }

    template<typename F, typename... Args>
    void f(const char* name) {
      std::cout << name << " is not predicate" << std::endl;
    }

    bool func1(int);
    int  func2(int);
    int* func3(int);
    auto lambda = [](auto a) { return a < 10; };

    struct predicate {
      bool operator()(int n) const {
        return n < 10;
      }
    };

    struct not_predicate {
      void operator()(int) {
      }
    };

    int main() {
      f<decltype(func1), int>("func1(int)");
      f<decltype(func2), int>("func2(int)");
      f<decltype(func3), int>("func3(int)");
      f<decltype(lambda), int>("lambda(int)");
      f<std::mt19937>("std::mt19937()");
      f<predicate, int>("predicate(int)");

      std::cout << "\n";
      f<not_predicate, int>("not_predicate(int)");
    }

### 出力

    func1(int) is predicate
    func2(int) is predicate
    func3(int) is predicate
    lambda(int) is predicate
    std::mt19937() is predicate
    predicate(int) is predicate

    not_predicate(int) is not predicate

## バージョン

### 言語

- C++20

### 処理系

- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 3 ✅

## 関連項目

- C++20 コンセプト

## 参照

- P0898R3 Standard Library Concepts
- P1754R1 Rename concepts to standard_case for C++20, while we still can