These operators do not perform lexicographical comparisons and seem to provide inconsistent results.
#include <iostream>
int main () {
std::cout << ("70" < "60") << '\n';
std::cout << ("60" < "70") << '\n';
return 0;
}
and
#include <iostream>
int main() {
std::cout << ("60" < "70") << '\n';
std::cout << ("70" < "60") << '\n';
return 0;
}
both print
1
0
The same holds true for std::less<>()
. However, std::less<std::string>()
provides the correct lexicographical comparison. What is the reason for this behaviour?
Are the comparisons shown above comparing the addresses of char arrays?
Character literals are character arrays. You are comparing these arrays, which after array-to-pointer decay means you are comparing the addresses of the first byte of these arrays.
Each character literal may refer to a different such array, even if it has the same value. And there is no guarantee about the order of their addresses.
So any possible outcome for your tests is allowed.
0
/0
as well as0
/1
,1
/0
and1
/1
.You can avoid all the C-style array behavior of string literals by always using
std::string
orstd::string_view
literals instead:This uses the user-defined string literal
operator""s
from the standard library to immediately formstd::string
s from the string literals.sv
can be used forstd::string_view
s instead. (string_view
will incur less performance cost, in particular no dynamic allocation.)