On Thu, 12 Nov 2026 at 16:31, Tomasz Kaminski <[email protected]> wrote:
>
> Title should say: Qualify
>
> On Thu, Nov 12, 2026 at 5:28 PM Tomasz Kamiński <[email protected]> wrote:
>>
>> These functions are forward declared in bits/stl_pair.h and defining
>> them using qualified name guarantees that signatures are matching.
>>
>> The deleted get<I>(const tuple<...>&) overloads for N > tuple_size is moved
>> to
>> bits/stl_pair.h, so the candidate set is the same regardless if tuple
>> is included.
>>
>> libstdc++-v3/ChangeLog:
>>
>> * include/bits/stl_pair.h (std::get(const tuple<...>&)): Moved
>> from...
>> * include/std/tuple (std::get<_Int>): Move deleted overload for out
>> of bounds index to bits/stl_pair.h. Qualify remaining definitions.
>> * include/std/array (std::get<_Int>): Qualify definitions.
>> * include/std/complex (std::get<_Int>): Qualify definitions.
>> ---
>> As discussed, this is worth doing as it would detect mismatches and
>> prevent problesm like PR128657.
>>
>> Testing on x86_64 and powerpc64-le. OK for trunk when all tests
>> passes?
OK
>>
>> libstdc++-v3/include/bits/stl_pair.h | 16 +++++++++++-----
>> libstdc++-v3/include/std/array | 8 ++++----
>> libstdc++-v3/include/std/complex | 9 +++++----
>> libstdc++-v3/include/std/tuple | 16 +++++-----------
>> 4 files changed, 25 insertions(+), 24 deletions(-)
>>
>> diff --git a/libstdc++-v3/include/bits/stl_pair.h
>> b/libstdc++-v3/include/bits/stl_pair.h
>> index ccff8691206..645e394520c 100644
>> --- a/libstdc++-v3/include/bits/stl_pair.h
>> +++ b/libstdc++-v3/include/bits/stl_pair.h
>> @@ -133,6 +133,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
>> get(const tuple<_Elements...>&& __t) noexcept;
>>
>> + /// @cond undocumented
>> + // Deleted overload chosen for invalid indices.
>> + template<size_t __i, typename... _Elements>
>> + constexpr __enable_if_t<(__i >= sizeof...(_Elements))>
>> + get(const tuple<_Elements...>&) = delete;
>> + /// @endcond
>> +
>> template<size_t _Int, typename _Tp, size_t _Nm>
>> constexpr _Tp&
>> get(array<_Tp, _Nm>&) noexcept;
>> @@ -1284,25 +1291,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>
>> template<size_t _Int, class _Tp1, class _Tp2>
>> constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
>> - get(pair<_Tp1, _Tp2>& __in) noexcept
>> + ::std::get(pair<_Tp1, _Tp2>& __in) noexcept
>> { return __pair_get<_Int>::__get(__in); }
>>
>> template<size_t _Int, class _Tp1, class _Tp2>
>> constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
>> - get(pair<_Tp1, _Tp2>&& __in) noexcept
>> + ::std::get(pair<_Tp1, _Tp2>&& __in) noexcept
>> { return __pair_get<_Int>::__move_get(std::move(__in)); }
>>
>> template<size_t _Int, class _Tp1, class _Tp2>
>> constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
>> - get(const pair<_Tp1, _Tp2>& __in) noexcept
>> + ::std::get(const pair<_Tp1, _Tp2>& __in) noexcept
>> { return __pair_get<_Int>::__const_get(__in); }
>>
>> template<size_t _Int, class _Tp1, class _Tp2>
>> constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
>> - get(const pair<_Tp1, _Tp2>&& __in) noexcept
>> + ::std::get(const pair<_Tp1, _Tp2>&& __in) noexcept
>> { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
>>
>> -
>> #ifdef __glibcxx_tuples_by_type // C++ >= 14
>> template <typename _Tp, typename _Up>
>> constexpr _Tp&
>> diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
>> index 5d3edbea649..77a3ce12154 100644
>> --- a/libstdc++-v3/include/std/array
>> +++ b/libstdc++-v3/include/std/array
>> @@ -392,7 +392,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> template<std::size_t _Int, typename _Tp, std::size_t _Nm>
>> [[__nodiscard__]]
>> constexpr _Tp&
>> - get(array<_Tp, _Nm>& __arr) noexcept
>> + ::std::get(array<_Tp, _Nm>& __arr) noexcept
>> {
>> static_assert(_Int < _Nm, "array index is within bounds");
>> return __arr._M_elems[_Int];
>> @@ -401,7 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> template<std::size_t _Int, typename _Tp, std::size_t _Nm>
>> [[__nodiscard__]]
>> constexpr _Tp&&
>> - get(array<_Tp, _Nm>&& __arr) noexcept
>> + ::std::get(array<_Tp, _Nm>&& __arr) noexcept
>> {
>> static_assert(_Int < _Nm, "array index is within bounds");
>> return std::move(std::get<_Int>(__arr));
>> @@ -410,7 +410,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> template<std::size_t _Int, typename _Tp, std::size_t _Nm>
>> [[__nodiscard__]]
>> constexpr const _Tp&
>> - get(const array<_Tp, _Nm>& __arr) noexcept
>> + ::std::get(const array<_Tp, _Nm>& __arr) noexcept
>> {
>> static_assert(_Int < _Nm, "array index is within bounds");
>> return __arr._M_elems[_Int];
>> @@ -419,7 +419,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> template<std::size_t _Int, typename _Tp, std::size_t _Nm>
>> [[__nodiscard__]]
>> constexpr const _Tp&&
>> - get(const array<_Tp, _Nm>&& __arr) noexcept
>> + ::std::get(const array<_Tp, _Nm>&& __arr) noexcept
>> {
>> static_assert(_Int < _Nm, "array index is within bounds");
>> return std::move(std::get<_Int>(__arr));
>> diff --git a/libstdc++-v3/include/std/complex
>> b/libstdc++-v3/include/std/complex
>> index 1be1c7abfb6..c1ea392af4c 100644
>> --- a/libstdc++-v3/include/std/complex
>> +++ b/libstdc++-v3/include/std/complex
>> @@ -638,10 +638,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> #endif
>>
>> #if __glibcxx_tuple_like >= 202311L // >= C++26
>> + // Forward declared in bits/stl_pair.h
>> template<size_t _Int, typename _Tp>
>> [[nodiscard,__gnu__::__always_inline__]]
>> constexpr _Tp&
>> - get(complex<_Tp>& __z) noexcept
>> + ::std::get(complex<_Tp>& __z) noexcept
>> {
>> static_assert(_Int < 2);
>> return __z.__get_part(_Int);
>> @@ -650,7 +651,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> template<size_t _Int, typename _Tp>
>> [[nodiscard,__gnu__::__always_inline__]]
>> constexpr _Tp&&
>> - get(complex<_Tp>&& __z) noexcept
>> + ::std::get(complex<_Tp>&& __z) noexcept
>> {
>> static_assert(_Int < 2);
>> return std::move(__z.__get_part(_Int));
>> @@ -659,7 +660,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> template<size_t _Int, typename _Tp>
>> [[nodiscard,__gnu__::__always_inline__]]
>> constexpr const _Tp&
>> - get(const complex<_Tp>& __z) noexcept
>> + ::std::get(const complex<_Tp>& __z) noexcept
>> {
>> static_assert(_Int < 2);
>> return __z.__get_part(_Int);
>> @@ -668,7 +669,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> template<size_t _Int, typename _Tp>
>> [[nodiscard,__gnu__::__always_inline__]]
>> constexpr const _Tp&&
>> - get(const complex<_Tp>&& __z) noexcept
>> + ::std::get(const complex<_Tp>&& __z) noexcept
>> {
>> static_assert(_Int < 2);
>> return std::move(__z.__get_part(_Int));
>> diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
>> index d73cefcbca8..4e28c3920b0 100644
>> --- a/libstdc++-v3/include/std/tuple
>> +++ b/libstdc++-v3/include/std/tuple
>> @@ -2462,22 +2462,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> __enable_if_t<(__i >= sizeof...(_Types))>
>> __get_helper(const tuple<_Types...>&) = delete;
>>
>> + // Declared in bits/stl_pair.h
>> /// Return a reference to the ith element of a tuple.
>> template<size_t __i, typename... _Elements>
>> constexpr __tuple_element_t<__i, tuple<_Elements...>>&
>> - get(tuple<_Elements...>& __t) noexcept
>> + ::std::get(tuple<_Elements...>& __t) noexcept
>> { return std::__get_helper<__i>(__t); }
>>
>> /// Return a const reference to the ith element of a const tuple.
>> template<size_t __i, typename... _Elements>
>> constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
>> - get(const tuple<_Elements...>& __t) noexcept
>> + ::std::get(const tuple<_Elements...>& __t) noexcept
>> { return std::__get_helper<__i>(__t); }
>>
>> /// Return an rvalue reference to the ith element of a tuple rvalue.
>> template<size_t __i, typename... _Elements>
>> constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
>> - get(tuple<_Elements...>&& __t) noexcept
>> + ::std::get(tuple<_Elements...>&& __t) noexcept
>> {
>> typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
>> return std::forward<__element_type>(std::__get_helper<__i>(__t));
>> @@ -2486,19 +2487,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> /// Return a const rvalue reference to the ith element of a const tuple
>> rvalue.
>> template<size_t __i, typename... _Elements>
>> constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
>> - get(const tuple<_Elements...>&& __t) noexcept
>> + ::std::get(const tuple<_Elements...>&& __t) noexcept
>> {
>> typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
>> return std::forward<const
>> __element_type>(std::__get_helper<__i>(__t));
>> }
>>
>> - /// @cond undocumented
>> - // Deleted overload chosen for invalid indices.
>> - template<size_t __i, typename... _Elements>
>> - constexpr __enable_if_t<(__i >= sizeof...(_Elements))>
>> - get(const tuple<_Elements...>&) = delete;
>> - /// @endcond
>> -
>> #ifdef __cpp_lib_tuples_by_type // C++ >= 14
>> /// Return a reference to the unique element of type _Tp of a tuple.
>> template <typename _Tp, typename... _Types>
>> --
>> 2.56.1
>>