On Thu, 12 Feb 2026, 21:44 Tomasz Kaminski, <[email protected]> wrote:
> > > 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. > Yes, that would be nice
