Date: Wed, 25 Nov 2020 19:51:13 +0100
Hi,
The less/greater than comparisons for unique_ptr allow for comparing
mixed pointer types (incl. fancy pointers). Given two unique_ptr
objects, these comparisons first convert both unique_ptr::pointer types
to their common_type, then compare the resulting common_type objects:
> http://eel.is/c++draft/unique.ptr.special#lib:operator%3c,unique_ptr
This kind of strategy was adopted as the resolution of LWG1401 / LWG1297:
> https://cplusplus.github.io/LWG/lwg-defects.html#1401
However, for some reason:
* operator== / operator!= don't do the same (they directly compare the
pointers, without first converting them both to their common_type)
* operator<=> added in C++20 doesn't do the same either, resulting in
compare_three_way being used on the two pointer types. If the pointer
types are different class types (e.g. fancy pointers) this will use
operator<=> between them, which is ill-formed.
In other words:
// assuming DelA, DelB::pointer are fancy pointers
// for which a common_type exists, etc.
std::unique_ptr<A, DelA> ptr_a;
std::unique_ptr<B, DelB> ptr_b;
if (ptr_a < ptr_b) ~~~ // works through common_type
if ((ptr_a <=> ptr_b) < 0) ~~~ // error
Was this a deliberate design decision trying to move away from the
handling via common_type, or was it an oversight when adopting <=> in
the Standard Library?
Thanks,
The less/greater than comparisons for unique_ptr allow for comparing
mixed pointer types (incl. fancy pointers). Given two unique_ptr
objects, these comparisons first convert both unique_ptr::pointer types
to their common_type, then compare the resulting common_type objects:
> http://eel.is/c++draft/unique.ptr.special#lib:operator%3c,unique_ptr
This kind of strategy was adopted as the resolution of LWG1401 / LWG1297:
> https://cplusplus.github.io/LWG/lwg-defects.html#1401
However, for some reason:
* operator== / operator!= don't do the same (they directly compare the
pointers, without first converting them both to their common_type)
* operator<=> added in C++20 doesn't do the same either, resulting in
compare_three_way being used on the two pointer types. If the pointer
types are different class types (e.g. fancy pointers) this will use
operator<=> between them, which is ill-formed.
In other words:
// assuming DelA, DelB::pointer are fancy pointers
// for which a common_type exists, etc.
std::unique_ptr<A, DelA> ptr_a;
std::unique_ptr<B, DelB> ptr_b;
if (ptr_a < ptr_b) ~~~ // works through common_type
if ((ptr_a <=> ptr_b) < 0) ~~~ // error
Was this a deliberate design decision trying to move away from the
handling via common_type, or was it an oversight when adopting <=> in
the Standard Library?
Thanks,
-- Giuseppe D'Angelo | giuseppe.dangelo_at_[hidden] | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts
Received on 2020-11-25 12:51:20