How does `std :: less` work?
Pointer relation operators do not define general ordering ( ยง 5.9 of the C ++ 11 standard ):
If two pointers
p
andq
the same type of point to different objects, which are not members of the same object or elements of the same array, or with different functions or if only one of them is zero, the results arep<q
,p>q
,p<=q
andp>=q
are not defined.
Partial specialization
std::less
for any pointer type gives complete ordering, even if inlineoperator<
doesn't work.
How does it return this general order from the partial order?
I cannot answer this question by looking /usr/include/c++/4.9/bits/stl_function.h
for struct less
definitions:
template<typename _Tp = void>
struct less;
template<typename _Tp>
struct less : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x < __y; }
};
template<>
struct less<void>
{
template <typename _Tp, typename _Up>
auto
operator()(_Tp&& __t, _Up&& __u) const
noexcept(noexcept(std::forward<_Tp>(__t) < std::forward<_Up>(__u)))
-> decltype(std::forward<_Tp>(__t) < std::forward<_Up>(__u))
{ return std::forward<_Tp>(__t) < std::forward<_Up>(__u); }
typedef __is_transparent is_transparent;
};
source to share
How does it return this general order from the partial order?
The standard rarely says how something should be done. Instead, it says what is required. And this is exactly the case. The standard requires to std::less
provide complete order, in ยง20.9.6 / 14:
For the higher, lower, higher, equal, and lower specialization patterns, for any pointer type, full order is given, even if the built-in operators <,>, <=,> = do not.
while the operator<
behavior in this regard is undefined according to ยง 5.9 / 4 (the quote you have in your question).
Undefined behavior is defined in 1.3.25:
for a well-formed program and correct data, which depends on the implementation [...]
Your specific implementation operator<
already provides complete ordering (probably because your pointer type is implemented as a 32-bit or 64-bit address, which is easy to interpret as something like an unsigned integer, which gives complete ordering), so it std::less
just redirects its arguments to this operator.
source to share