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.