https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115775

            Bug ID: 115775
           Summary: User-defined deduction guide ignored for alias
                    template if the alias passes on a template template
                    parameter to the aliased class template
           Product: gcc
           Version: 14.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: s.murthy at outlook dot com
  Target Milestone: ---

In the source code below, the alias template A2 instantiated without an
argument for template template parameter V is effectively the same as
instantiating the alias template A1, yet the deduction guide 2 is used only for
A1 but is ignored for A2.

I believe deduction guide 2 should be used for both the variables a1 and a2 in
this code.

Please forgive me if my understanding of user-defined deduction guides is
incorrect and it is my guides that are incorrect. I don't mean to waste
anyone's time.

Repro (see: https://sigcpp.godbolt.org/z/hEn6zhWWE)
---------------------------------------------------

template<bool B> class dv;

template<bool B = false, std::unsigned_integral U = unsigned,
         template<bool> class V = dv
        >
struct C {
    U u;

    C(std::signed_integral auto n) : u( n < 0 ? -n : n) {}
};

template<std::unsigned_integral U = unsigned, 
         template<bool> class V = dv //superfluous, but illustrative
        >
using A1 = C<true, U>; //force default V: same as A2 instantiated without V arg

template<std::unsigned_integral U = unsigned, 
         template<bool> class V = dv
        >
using A2 = C<true, U, V>; //pass V along: same as A1 if instantiated without V
arg


//guide 1
template <std::signed_integral SI>
C(SI) -> C<false, std::make_unsigned_t<SI>>;

//guide 2
template <bool B, std::signed_integral SI>
explicit C(SI) -> C<B, std::make_unsigned_t<SI>>;


int main()
{
    auto c1 = C(45l); //guide 1, U is ulong
    static_assert(std::is_same_v<decltype(c1.u), unsigned long>); //pass

    auto a1 = A1(45l); //guide 2, U is ulong
    static_assert(std::is_same_v<decltype(a1.u), unsigned long>); //pass

    auto a2 = A2(45l); //expect to use guide 2, U should be ulong
    static_assert(std::is_same_v<decltype(a2.u), unsigned long>); //fail
}

Reply via email to