Consider this code:
#include <functional>
#include <typeinfo>
template <typename T>
inline constexpr const void *foo = &typeid(T);
int main()
{
    constexpr bool a = std::less<const void*>{}(foo<int>, foo<float>);
} 
If I use < instead of std::less here, the code doesn't compile. This is not surprising, because the result of a relational pointer comparsion is unspecified if the pointers point to unrelated objects, and apparently such a comparsion can't be done at compile-time.
<source>:9:20: error: constexpr variable 'a' must be initialized by a constant expression constexpr bool a = foo<int> < foo<float>; ^ ~~~~~~~~~~~~~~~~~~~~~ <source>:9:33: note: comparison has unspecified value constexpr bool a = foo<int> < foo<float>; ^
The code still doesn't compile, even if I use std::less. The compiler error is the same. std::less appears to be implemented as < in at least libstdc++ and libc++; I get the same results on GCC, Clang, and MSVC.
However, the cppreference page about std::less claims that:
- Its - operator()is- constexpr.
- It magically implements strict total order on pointers, i.e. can be used to compare unrelated pointers with sensible results. 
So, is it a bug in all those compilers, or am I missing some detail about std::less that makes the code above ill-formed?
 
     
     
     
    