Changing comparison criteria at runtime
Can I use standard library algorithms with different comparison criteria at runtime?
Yes, you can use std::ranges
algorithms with different comparison criteria at runtime by passing custom comparison functions.
This flexibility allows you to adapt the algorithms to various needs dynamically.
Using Custom Comparison Functions
Custom comparison functions can be defined as lambdas or regular functions and passed to the algorithms. Here's how you can do it:
Example with std::ranges::min_element()
Consider a Player
class where you might want to find the player with the minimum or maximum health or score based on different criteria at runtime.
#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
class Player {/*...*/};
int main() {
std::vector<Player> Party {
{"Roderick", 100, 500},
{"Anna", 200, 800},
{"Robert", 150, 300}
};
// Runtime choice of comparison criteria
auto CompareByHealth = [](
const Player& a, const Player& b) {
return a.GetHealth() < b.GetHealth();
};
auto CompareByScore = [](
const Player& a, const Player& b) {
return a.GetScore() < b.GetScore();
};
// Using CompareByHealth
auto minHealthIt = std::ranges::min_element(
Party, CompareByHealth);
std::cout << "Player with the least health: "
<< minHealthIt->GetName() << " ("
<< minHealthIt->GetHealth() << ")\n";
// Using CompareByScore
auto minScoreIt = std::ranges::min_element(
Party, CompareByScore);
std::cout << "Player with the least score: "
<< minScoreIt->GetName() << " ("
<< minScoreIt->GetScore() << ")";
}
Player with the least health: Roderick (100)
Player with the least score: Robert (300)
Explanation
- Custom Comparisons: Define multiple comparison functions to compare
Player
objects by different attributes likeHealth
andScore
. - Runtime Selection: Pass the appropriate comparison function to
std::ranges::min_element()
based on the desired criteria at runtime.
Generalizing with Function Pointers or std::function
You can also use function pointers or std::function
for even more flexibility in selecting the comparison criteria at runtime.
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <functional>
class Player {/*...*/};
int main() {
std::vector<Player> Party{
{"Roderick", 100, 500},
{"Anna", 200, 800},
{"Robert", 150, 300}
};
std::function<bool(
const Player&, const Player&)> comparator;
// This can be set at runtime
bool compareByHealth = true;
if (compareByHealth) {
comparator = [](const Player& a, const Player& b) {
return a.GetHealth() < b.GetHealth();
};
} else {
comparator = [](const Player& a, const Player& b) {
return a.GetScore() < b.GetScore();
};
}
auto minElementIt =
std::ranges::min_element(Party, comparator);
std::cout
<< "Player with the minimum selected criteria: "
<< minElementIt->GetName();
}
Player with the minimum selected criteria: Roderick
Summary
Using std::ranges
algorithms with different comparison criteria at runtime is straightforward. By defining and passing custom comparison functions, you can adapt the behavior of these algorithms to meet various requirements dynamically.
Minimum and Maximum Algorithms
An introduction to the seven minimum and maximum algorithms in the C++ standard library: clamp()
, min()
, min_element()
, max()
, max_element()
, minmax()
, and minmax_element()
.