https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114400
Bug ID: 114400 Summary: The resolution of LWG3950 seems incorrectly implemented Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following example fails to compile with libstdc++ due to ambiguity in overload resolution (https://godbolt.org/z/Ya5o4rrKj). ``` #include <string> #include <string_view> #include <type_traits> namespace test { template<class Traits> concept characterized_traits = requires { typename Traits::is_characterized; }; template<class CharT> struct test_traits : std::char_traits<CharT> { using is_characterized = void; }; template<class Traits> struct traits_comparison_category { using type = std::weak_ordering; }; template<class Traits> requires requires { typename Traits::comparison_category; } struct traits_comparison_category<Traits> { using type = Traits::comparison_category; static_assert(std::disjunction_v< std::is_same<type, std::partial_ordering>, std::is_same<type, std::weak_ordering>, std::is_same<type, std::strong_ordering>>); }; // N.B. std::type_identity_t is exactly used. template<class CharT, characterized_traits Traits> constexpr bool operator==( std::basic_string_view<CharT, Traits> x, std::type_identity_t<std::basic_string_view<CharT, Traits>> y) noexcept { return x.size() == y.size() && x.compare(y) == 0; } template<class CharT, characterized_traits Traits> constexpr traits_comparison_category<Traits>::type operator<=>( std::basic_string_view<CharT, Traits> x, std::type_identity_t<std::basic_string_view<CharT, Traits>> y) noexcept { return static_cast<traits_comparison_category<Traits>::type>(x.compare(y) <=> 0); } using test_string_view = std::basic_string_view<char, test_traits<char>>; static_assert(test_string_view{} == test_string_view{}); static_assert(test_string_view{} == ""); static_assert("" == test_string_view{}); static_assert(test_string_view{} <=> test_string_view{} == std::strong_ordering::equal); static_assert(test_string_view{} <=> "" == std::strong_ordering::equal); static_assert("" <=> test_string_view{} == std::strong_ordering::equal); } ``` The resolution of LWG3950 (https://cplusplus.github.io/LWG/issue3950) uses `type_identity_t`, while libstdc++ currently uses `__type_identity_t`. The difference between two alias templates can be observed by partial ordering introduced by associated constraints. Related PR in MSVC STL: https://github.com/microsoft/STL/pull/4249