C++20coreadvanced
std::weak_ordering (C++20 Addition)
C++20 · The Big Four · Compiler flag: -std=c++20
Explanation
Comparison result type for weak ordering (e.g., case-insensitive strings).
Real-World Scenario
Sort usernames case-insensitively in a user management system.
Quick Snippet
snippet.cpp
#include <compare> std::weak_ordering result = str1 <=> str2;Full Example
weak_ordering.cpp
// CodeNebula - C++20 Example: Weak Ordering
// Compile: g++ -std=c++20 -Wall -Wextra -o example weak_ordering.cpp
// Demonstrates std::weak_ordering: values are equivalent but not necessarily
// equal (e.g., case-insensitive string comparison, priority without identity).
#include <iostream>
#include <compare>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
// ------------------------------------------------------------------
// 1. Case-insensitive string wrapper
// ------------------------------------------------------------------
struct CIString {
std::string value;
std::weak_ordering operator<=>(const CIString& other) const {
auto to_lower = [](const std::string& s) {
std::string result = s;
for (auto& c : result) c = static_cast<char>(std::tolower(c));
return result;
};
std::string a = to_lower(value);
std::string b = to_lower(other.value);
if (a < b) return std::weak_ordering::less;
if (a > b) return std::weak_ordering::greater;
return std::weak_ordering::equivalent;
}
bool operator==(const CIString& other) const {
return (*this <=> other) == 0;
}
};
// ------------------------------------------------------------------
// 2. Priority-based comparison (weak ordering by rank)
// ------------------------------------------------------------------
struct Task {
std::string name;
int priority; // lower = more urgent
// Two tasks with same priority are equivalent but not identical
std::weak_ordering operator<=>(const Task& other) const {
return priority <=> other.priority;
}
bool operator==(const Task& other) const {
return priority == other.priority;
}
};
// ------------------------------------------------------------------
// 3. Checking weak_ordering result values
// ------------------------------------------------------------------
void describe_weak(std::weak_ordering ord, const char* expr) {
std::cout << " " << expr << " is ";
if (ord == std::weak_ordering::less) std::cout << "less";
else if (ord == std::weak_ordering::equivalent) std::cout << "equivalent";
else if (ord == std::weak_ordering::greater) std::cout << "greater";
std::cout << std::endl;
}
int main()
{
std::cout << "=== Case-Insensitive Comparison ===" << std::endl;
CIString a{"Hello"}, b{"hello"}, c{"World"}, d{"HELLO"};
std::cout << " 'Hello' == 'hello'? " << (a == b) << std::endl;
std::cout << " 'Hello' == 'HELLO'? " << (a == d) << std::endl;
std::cout << " 'Hello' < 'World'? " << (a < c) << std::endl;
describe_weak(a <=> b, "'Hello' <=> 'hello'");
describe_weak(a <=> c, "'Hello' <=> 'World'");
std::cout << "\n=== Sorting Case-Insensitive ===" << std::endl;
std::vector<CIString> words = {
{"Banana"}, {"apple"}, {"CHERRY"}, {"date"}, {"Apple"}
};
std::sort(words.begin(), words.end());
for (const auto& w : words)
std::cout << " " << w.value << std::endl;
std::cout << "\n=== Task Priority (Weak Ordering) ===" << std::endl;
std::vector<Task> tasks = {
{"Write docs", 3},
{"Fix bug", 1},
{"Code review", 2},
{"Deploy", 1},
{"Refactor", 3}
};
std::sort(tasks.begin(), tasks.end());
for (const auto& t : tasks) {
std::cout << " [P" << t.priority << "] " << t.name << std::endl;
}
std::cout << "\n 'Fix bug' == 'Deploy'? (same priority) "
<< (tasks[0] == tasks[1]) << std::endl;
std::cout << "\n=== weak_ordering Has No 'equal' ===" << std::endl;
// weak_ordering only has: less, equivalent, greater (no "equal")
std::cout << " less < 0? " << (std::weak_ordering::less < 0) << std::endl;
std::cout << " equivalent == 0? " << (std::weak_ordering::equivalent == 0) << std::endl;
std::cout << " greater > 0? " << (std::weak_ordering::greater > 0) << std::endl;
std::cout << "\n=== Conversion ===" << std::endl;
std::weak_ordering wo = std::weak_ordering::less;
std::partial_ordering po = wo; // implicit conversion ok
std::cout << " weak->partial (< 0)? " << (po < 0) << std::endl;
// std::strong_ordering so = wo; // ERROR: cannot convert weak to strong
return 0;
}
/*
Expected output:
=== Case-Insensitive Comparison ===
'Hello' == 'hello'? 1
'Hello' == 'HELLO'? 1
'Hello' < 'World'? 1
'Hello' <=> 'hello' is equivalent
'Hello' <=> 'World' is less
=== Sorting Case-Insensitive ===
apple
Apple
Banana
CHERRY
date
=== Task Priority (Weak Ordering) ===
[P1] Fix bug
[P1] Deploy
[P2] Code review
[P3] Write docs
[P3] Refactor
'Fix bug' == 'Deploy'? (same priority) 1
=== weak_ordering Has No 'equal' ===
less < 0? 1
equivalent == 0? 1
greater > 0? 1
=== Conversion ===
weak->partial (< 0)? 1
*/
Run command
g++ -std=c++20 -Wall -Wextra -o example weak_ordering.cpp