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/0as well as0/1,1/0and1/1.You can avoid all the C-style array behavior of string literals by always using
std::stringorstd::string_viewliterals instead:This uses the user-defined string literal
operator""sfrom the standard library to immediately formstd::strings from the string literals.svcan be used forstd::string_views instead. (string_viewwill incur less performance cost, in particular no dynamic allocation.)