Using the Predicate Concept with Member Types

Can I use the std::predicate concept with member functions that take member types as arguments?

Yes, you can use the std::predicate concept with member functions that take member types as arguments. However, you need to specify the class scope when referring to the member types in the concept.

Here's an example:

#include <concepts>
#include <functional>
#include <iostream>

class Vehicle {
 public:
  struct Specs {
    int maxSpeed;
    int weight;
  };

  bool isHeavy(const Specs& specs) const {
    return specs.weight > 3000; }
};

template <typename T>
concept HeavyVehicle = std::predicate<
  bool (T::*)(const typename T::Specs&) const,
  T, typename T::Specs
>;

template <HeavyVehicle T>
void checkIfHeavy(const T& obj,
  const typename T::Specs& specs) {
  if (std::invoke(&T::isHeavy, obj, specs)) {
    std::cout << "The vehicle is heavy.\n";
  } else {
    std::cout << "The vehicle is not heavy.\n";
  }
}

int main() {
  Vehicle car;
  Vehicle::Specs carSpecs{150, 2500};
  checkIfHeavy(car, carSpecs);

  carSpecs.weight = 3500;
  checkIfHeavy(car, carSpecs);
}
The vehicle is not heavy.
The vehicle is heavy.

In this example, the Vehicle class has a member type Specs and a member function isHeavy that takes a Specs object as an argument.

We define a HeavyVehicle concept that checks if a type T has a member function isHeavy that is a predicate (returns a boolean) and takes a T::Specs object as an argument. The use of std::predicate ensures that we are conforming to the expectations of a predicate function in the C++ standard library.

In the checkIfHeavy function template, we constrain the type T to satisfy the HeavyVehicle concept. We also use typename T::Specs to refer to the Specs member type of T.

In main, we create a Vehicle object and a Vehicle::Specs object, and call checkIfHeavy with these objects. The isHeavy member function is correctly called based on the HeavyVehicle concept.

Note that when referring to the member type in the concept (typename T::Specs), we need to use the typename keyword to indicate that Specs is a type and not a value.

Standard Library Function Helpers

A comprehensive overview of function helpers in the standard library, including std::invocable, std::predicate and std::function.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Calling an Empty std::function
What happens if I try to call a std::function object that is empty?
Performance Considerations with std::function
Are there any performance considerations I should be aware of when using std::function?
Storing Member Functions in std::function
Can I store a member function in a std::function object? If so, how do I invoke it?
Invoking Multiple std::function Objects
How can I store and invoke multiple std::function objects?
Using Lambdas with std::function
Can I use lambda expressions with std::function? Are there any limitations?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant