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.
Answers to questions are automatically generated and may not have been reviewed.
A comprehensive overview of function helpers in the standard library, including std::invocable
, std::predicate
and std::function
.