Standard Library Function Helpers

Using the Predicate Concept with Member Types

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

Abstract art representing computer programming

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 computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved