[Bug c++/111504] compare operator not defined for recursive data types on C++20
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111504 --- Comment #3 from Xiang Gao --- Cross posted at: https://github.com/llvm/llvm-project/issues/67056
[Bug c++/111504] compare operator not defined for recursive data types on C++20
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111504 --- Comment #2 from Xiang Gao --- (In reply to Andrew Pinski from comment #1) > Fails for the same reason with clang (both with libstdc++ and libc++) > > Are you sure this is valid C++ 20 code? I am not 100% sure, but my understanding is, for the SFINAE in inline constexpr bool operator<(const DT& x, const DT& y) The first condition hasLessThan::value is just hasLessThan::value, which should be true, and (true || anything) is always true. So the condition in SFINAE should be easily evaluated as true. So the operator< for DynamicType should be defined. And if operator< is defined, then the operator<=> of std::vector should also be defined. This can be validated by changing the definition of operator< by only keeping the first condition: template < typename DT, typename = std::enable_if_t< (hasLessThan::value)>> inline constexpr bool operator<(const DT& x, const DT& y) { // implementation omitted return true; } and then both g++ and clang++ will pass. I do observe the same error on clang, but this https://cpp.sh/ seems to compile without problem on C++20.
[Bug c++/111504] New: compare operator not defined for recursive data types on C++20
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111504 Bug ID: 111504 Summary: compare operator not defined for recursive data types on C++20 Product: gcc Version: 13.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: xgao at nvidia dot com Target Milestone: --- Related bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111316 The following code works on C++17 but not C++20: #include #include #include template static auto hasLessThanHelper(int) -> decltype(std::declval() < std::declval(), std::true_type{}); template static auto hasLessThanHelper(long) -> std::false_type; template struct hasLessThan : decltype(hasLessThanHelper(0)) {}; struct DynamicType { using T1 = int64_t; using T2 = std::vector; }; template < typename DT, typename = std::enable_if_t< (hasLessThan::value || hasLessThan::value || hasLessThan::value || hasLessThan::value)>> inline constexpr bool operator<(const DT& x, const DT& y) { // implementation omitted return true; } int main() { using DT = DynamicType; // This assert works on C++17, but fails on C++20 static_assert(hasLessThan, std::vector>::value); }
[Bug c++/111316] New: std::vector's operator < does not work with recursive data type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111316 Bug ID: 111316 Summary: std::vector's operator < does not work with recursive data type Product: gcc Version: 13.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: xgao at nvidia dot com Target Milestone: --- Created attachment 55847 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55847&action=edit minimum repro The attached minimal repro does not work on g++ on C++20, but it works with g++ on C++17 and clang++ on both C++17 and C++20. See the code for detail: Error message: /usr/include/c++/13.2.1/compare:1216:18: error: satisfaction of atomic constraint ‘requires{{__t < __u} -> decltype(auto) [requires std::__detail::__boolean_testable<, >];{__u < __t} -> decltype(auto) [requires std::__detail::__boolean_testable<, >];} [with _Tp = _Tp; _Up = _Up]’ depends on itself
[Bug c++/111314] New: Can not deduct parameter pack as a single type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111314 Bug ID: 111314 Summary: Can not deduct parameter pack as a single type Product: gcc Version: 13.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: xgao at nvidia dot com Target Milestone: --- The following code does not work: #include template struct Template {}; template typename, typename> struct DynamicType {}; template struct is_dynamic_type : std::false_type {}; template typename Template, typename... Ts> struct is_dynamic_type> : std::true_type {}; template constexpr bool is_dynamic_type_v = is_dynamic_type::value; // This fails: static_assert(is_dynamic_type_v>); int main() {}
[Bug libstdc++/110594] New: std::variant's converting constructor does not resolve alternative correctly
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110594 Bug ID: 110594 Summary: std::variant's converting constructor does not resolve alternative correctly Product: gcc Version: 13.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: xgao at nvidia dot com Target Milestone: --- Created attachment 55502 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55502&action=edit minimum repro According to https://en.cppreference.com/w/cpp/utility/variant/variant, I would expect the attached program to output: int64_t: 1 variant is int However, I am getting: int64_t: 1 variant is complex gcc-9 seems to have the correct behavior for the attached program, however, the implementation of std::variant in gcc-9 has another problem that the following example in that cppreference.com page does not work: std::variant z = 0; // OK, holds long // float and double are not candidates Thanks to the help of jjsjann123 (https://github.com/jjsjann123), this is potentially related to the SFINAE in the "variant" header: // Helper used to check for valid conversions that don't involve narrowing. template struct _Arr { _Ti _M_x[1]; }; seems that this will block int64_t from being selected as shown in https://godbolt.org/z/Gcr4j53rd. However, the following code is totally valid: int64_t x[] = {size_t(1)}; so probably that SFINAE might be wrong.