<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Fri, Oct 17, 2025 at 6:27 PM Hewill Kang <<a href="mailto:hewillk@gmail.com">hewillk@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I'm not sure what you mean, but it does weird to me that the underlying types can't be compared, but the corresponding tuple-like can be compared:<br><br><div style="color:rgb(0,0,0);background-color:rgb(255,255,254);font-family:Consolas,"Liberation Mono",Courier,monospace,Menlo,Monaco,"Courier New",monospace;font-size:14px;line-height:21px;white-space:pre-wrap"><div><span style="color:rgb(0,0,255)">#include</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">tuple</span><span style="color:rgb(0,0,255)">></span></div><div><span style="color:rgb(0,0,255)">#include</span> <span style="color:rgb(0,0,255)"><</span><span style="color:rgb(163,21,21)">array</span><span style="color:rgb(0,0,255)">></span></div><br><div><span style="color:rgb(0,0,255)">struct</span> S {</div><div>  <span style="color:rgb(0,0,255)">void</span> <span style="color:rgb(0,0,255)">operator</span>== (<span style="color:rgb(0,0,255)">const</span> S&) <span style="color:rgb(0,0,255)">const</span> = <span style="color:rgb(0,0,255)">delete</span>;</div><div>  <span style="color:rgb(0,0,255)">void</span> <span style="color:rgb(0,0,255)">operator</span><=>(<span style="color:rgb(0,0,255)">const</span> S&) <span style="color:rgb(0,0,255)">const</span> = <span style="color:rgb(0,0,255)">delete</span>;</div><div>  <span style="color:rgb(0,0,255)">void</span> <span style="color:rgb(0,0,255)">operator</span>  <(<span style="color:rgb(0,0,255)">const</span> S&) <span style="color:rgb(0,0,255)">const</span> = <span style="color:rgb(0,0,255)">delete</span>;</div><div>};</div><br><div><span style="color:rgb(0,0,255)">int</span> main() {</div><div>  std::tuple<> t;</div><div>  std::array<S, <span style="color:rgb(9,134,88)">0</span>> a;</div><div>  <span style="color:rgb(0,128,0)">// a == a; // error</span></div><div>  t  < a;  <span style="color:rgb(0,128,0)">// ok</span></div></div></div></blockquote><div>Yes, because the < is doing more efficient implementation of:<br></div><div>       t < std::tuple<>(a);</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="color:rgb(0,0,0);background-color:rgb(255,255,254);font-family:Consolas,"Liberation Mono",Courier,monospace,Menlo,Monaco,"Courier New",monospace;font-size:14px;line-height:21px;white-space:pre-wrap"><div>  t == a;  <span style="color:rgb(0,128,0)">// ok</span></div><div>  t <=> a; <span style="color:rgb(0,128,0)">// ok</span></div><div>}</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Tomasz Kaminski <<a href="mailto:tkaminsk@redhat.com" target="_blank">tkaminsk@redhat.com</a>> 於 2025年10月18日 週六 上午12:20寫道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Oct 17, 2025 at 6:00 PM Hewill Kang <<a href="mailto:hewillk@gmail.com" target="_blank">hewillk@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Wow, I just noticed that the current wording allows tuple<> to be compared to any array<T, 0>, regardless of the type of T.<br>However, tuple<T> can only be compared to array<T, 1> if T itself is comparable.<br></div></blockquote><div>They common_reference is tuple<>, but they are not totally_ordered_with, as array is not ordered. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">This seems to be a defect.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Osama Abdelkader <<a href="mailto:osama.abdelkader@gmail.com" target="_blank">osama.abdelkader@gmail.com</a>> 於 2025年10月17日 週五 下午11:27寫道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Fixes #119721<br>
<br>
This fixes a C++23 compliance issue where std::tuple<> cannot be compared<br>
with std::array<T, 0>. Both are empty tuple-like types and should be<br>
comparable according to the C++23 standard.<br>
<br>
The fix adds the missing comparison operators:<br>
- operator== and operator!= (return true and false respectively)<br>
- operator<, operator<=, operator>, operator>= (follow ordering rules for empty types)<br>
- operator<=> (returns strong_ordering::equal)<br>
<br>
This resolves the 'rejects-valid' bug where GCC was rejecting valid C++23 code<br>
that Clang with libc++ already supports correctly.<br>
<br>
libstdc++-v3/ChangeLog:<br>
<br>
        * include/std/tuple: Add comparison operators between tuple<> and array<T, 0>.<br>
<br>
Signed-off-by: Osama Abdelkader <<a href="mailto:osama.abdelkader@gmail.com" target="_blank">osama.abdelkader@gmail.com</a>><br>
---<br>
 libstdc++-v3/include/std/tuple | 88 ++++++++++++++++++++++++++++++++++<br>
 1 file changed, 88 insertions(+)<br>
<br>
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple<br>
index 0ca616f1b..d3621dd16 100644<br>
--- a/libstdc++-v3/include/std/tuple<br>
+++ b/libstdc++-v3/include/std/tuple<br>
@@ -1880,6 +1880,94 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION<br>
          using _Cat = typename __tuple_like_common_comparison_category<_UTuple>::type;<br>
          return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Elements...>());<br>
        }<br>
+<br>
+  // Comparison operators between tuple<> and array<T, 0><br>
+  // These are needed because both are empty tuple-like types in C++23<br>
+  <br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator==(const tuple<>&, const array<_Tp, 0>&)<br>
+    { return true; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator==(const array<_Tp, 0>&, const tuple<>&)<br>
+    { return true; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator!=(const tuple<>&, const array<_Tp, 0>&)<br>
+    { return false; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator!=(const array<_Tp, 0>&, const tuple<>&)<br>
+    { return false; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator<(const tuple<>&, const array<_Tp, 0>&)<br>
+    { return false; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator<(const array<_Tp, 0>&, const tuple<>&)<br>
+    { return false; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator<=(const tuple<>&, const array<_Tp, 0>&)<br>
+    { return true; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator<=(const array<_Tp, 0>&, const tuple<>&)<br>
+    { return true; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator>(const tuple<>&, const array<_Tp, 0>&)<br>
+    { return false; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator>(const array<_Tp, 0>&, const tuple<>&)<br>
+    { return false; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator>=(const tuple<>&, const array<_Tp, 0>&)<br>
+    { return true; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr bool<br>
+    operator>=(const array<_Tp, 0>&, const tuple<>&)<br>
+    { return true; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr strong_ordering<br>
+    operator<=>(const tuple<>&, const array<_Tp, 0>&)<br>
+    { return strong_ordering::equal; }<br>
+<br>
+  template<typename _Tp><br>
+    [[nodiscard]]<br>
+    constexpr strong_ordering<br>
+    operator<=>(const array<_Tp, 0>&, const tuple<>&)<br>
+    { return strong_ordering::equal; }<br>
+<br>
 #endif // C++23<br>
<br>
 #else // ! (concepts && consteval)<br>
-- <br>
2.43.0<br>
<br>
</blockquote></div>
</blockquote></div></div>
</blockquote></div>
</blockquote></div></div>