C++20stladvanced
std::equality_comparable (C++20 Addition)
C++20 · The Big Four · Compiler flag: -std=c++20
Explanation
Concept that checks if a type supports `==` and `!=` operators with boolean results. The two-type variant `equality_comparable_with` checks cross-type equality.
Real-World Scenario
Constrain a deduplication algorithm to types that can be compared for equality.
Quick Snippet
snippet.cpp
#include <concepts>
#include <vector>
#include <algorithm>
template<std::equality_comparable T>
std::vector<T> deduplicate(std::vector<T> items) {
std::vector<T> result;
for (auto& item : items)
if (std::ranges::find(result, item) == result.end())
result.push_back(std::move(item));
return result;
}Full Example
equality_comparable.cpp
// CodeNebula - C++20 Example: std::equality_comparable Concept
// Compile: g++ -std=c++20 -Wall -Wextra -o example equality_comparable.cpp
// std::equality_comparable<T> is satisfied when T supports == and !=
// operators that return bool. std::equality_comparable_with<T, U>
// extends this to cross-type comparisons.
#include <concepts>
#include <iostream>
#include <string>
#include <vector>
struct Point {
int x, y;
bool operator==(const Point&) const = default; // C++20 defaulted
};
struct Color {
int r, g, b;
// No operator== defined
};
// Find an element in a range (requires equality_comparable)
template <std::equality_comparable T>
int find_index(const std::vector<T>& vec, const T& target) {
for (std::size_t i = 0; i < vec.size(); ++i) {
if (vec[i] == target) return static_cast<int>(i);
}
return -1;
}
// Count occurrences
template <std::equality_comparable T>
int count(const std::vector<T>& vec, const T& target) {
int result = 0;
for (const auto& elem : vec) {
if (elem == target) ++result;
}
return result;
}
// Check all elements are equal
template <std::equality_comparable T>
bool all_equal(const std::vector<T>& vec) {
if (vec.empty()) return true;
for (std::size_t i = 1; i < vec.size(); ++i) {
if (!(vec[i] == vec[0])) return false;
}
return true;
}
int main() {
// Find in vector of ints
std::vector<int> nums = {10, 20, 30, 40, 50};
std::cout << "Index of 30: " << find_index(nums, 30) << "\n";
std::cout << "Index of 99: " << find_index(nums, 99) << "\n";
// Find in vector of strings
std::vector<std::string> words = {"apple", "banana", "cherry"};
std::cout << "Index of banana: " << find_index(words, std::string("banana")) << "\n";
// Count occurrences
std::vector<int> data = {1, 2, 3, 2, 4, 2, 5};
std::cout << "Count of 2: " << count(data, 2) << "\n";
// Find with Points (uses defaulted ==)
std::vector<Point> pts = {{0,0}, {1,2}, {3,4}};
std::cout << "Index of (1,2): " << find_index(pts, Point{1, 2}) << "\n";
// All equal check
std::vector<int> same = {7, 7, 7, 7};
std::vector<int> diff = {7, 7, 8, 7};
std::cout << "All equal {7,7,7,7}: " << all_equal(same) << "\n";
std::cout << "All equal {7,7,8,7}: " << all_equal(diff) << "\n";
// Concept checks
std::cout << "\nEquality comparable:\n";
std::cout << "int: " << std::equality_comparable<int> << "\n";
std::cout << "Point: " << std::equality_comparable<Point> << "\n";
std::cout << "Color: " << std::equality_comparable<Color> << "\n";
return 0;
}
// Expected output:
// Index of 30: 2
// Index of 99: -1
// Index of banana: 1
// Count of 2: 3
// Index of (1,2): 1
// All equal {7,7,7,7}: 1
// All equal {7,7,8,7}: 0
//
// Equality comparable:
// int: 1
// Point: 1
// Color: 0
Run command
g++ -std=c++20 -Wall -Wextra -o example equality_comparable.cpp