On Thu, Feb 12, 2026 at 10:35 PM Patrick Palka <[email protected]> wrote:

> On Thu, Feb 12, 2026 at 4:23 PM Tomasz Kaminski <[email protected]>
> wrote:
> >
> >
> >
> > On Thu, Feb 12, 2026 at 9:04 PM Ville Voutilainen <
> [email protected]> wrote:
> >>
> >> On Thu, 12 Feb 2026 at 21:52, Jonathan Wakely <[email protected]>
> wrote:
> >> >
> >> > This is similar to the r16-3536-g0bb0d1d2880d56 change for std::pair,
> so
> >> > that CTAD ignores the tuple(const Types&...) constructor and only uses
> >> > the tuple(Types...) -> tuple<Types...> deduction guide. This ensures
> >> > that the deduced type comes from the decayed argument types.
> >> >
> >> > libstdc++-v3/ChangeLog:
> >> >
> >> >         PR libstdc++/121771
> >> >         * include/std/tuple (tuple::tuple(const Elements&...)): Use
> >> >         type_identity_t to prevent constructor being used for CTAD.
> >> >         (tuple::tuple(allocator_arg_t, const A&, const Elements&...)):
> >> >         Likewise.
> >> >         * testsuite/20_util/tuple/cons/121771.cc: New test.
> >> > ---
> >> >
> >> > Tested aarch64-linux.
> >>
> >> FWIW, LGTM.
> >
> > OK to merge it now, but I believe this is bug in GCC and we should open
> an issue for it.
> > The  generated deduction guides are equivalent to:
> > template<typename... Args>
> > void foo(const Args&...);
> > template<typename... Args>
> > void foo(Args...);
> >
> > And for such overload, the call foo(bar) where bar is function is
> ambiguous
> > (https://godbolt.org/z/f96Mb5E1n), so they should get disambiguated by:
> > https://eel.is/c++draft/over.match#best.general-2.11
> > > F1 is generated from a deduction-guide ([over.match.class.deduct]) and
> F2 is not, or, if not that,
> We don't get that far, we hit a hard error when checking constraints
> on the implicit guide because they're in terms of class-scope helpers
> so we need to instantiate an ill-formed tuple specialization.
>
> There's more info in the corresponding std::pair bug:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110853
>
> Ah, the constructor uses:
      template<typename... _UTypes>
        static consteval bool
        __constructible()
        {
          if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
            return __and_v<is_constructible<_Elements, _UTypes>...>;
          else
            return false;
        }
That is a member of the tuple, so we deduce the arguments, and want to
check tuple<_Elements...>::constructible(),
which does instantiate it with deduced arguments. So we brought the problem
on ourselves by declaring the funciton
used as constraints as a member of the tuple.

So, no bug in GCC, and this seems to be the correct fix. We should have
language feature that would enable
opting out of implicit CTAD.

Reply via email to