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