<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>