C++ Logo


Advanced search

Re: Remove restriction on deduction guides.

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sat, 20 Feb 2021 11:32:02 -0500
On Sat, Feb 20, 2021 at 9:14 AM Bengt Gustafsson via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> I just noted that a deduction guide needs the stated return type to be exactly the name of the class template whose instance is being deduced, a metafunction call is not allowed. In my use case I wanted a class template to adapt to the signature of a callable sent as constructor parameter. This does not seem to be possible in C++20.
> I don't see a compelling reason to require the class template name to be written out verbatim after the -> of the deduction guide, at this point in the parsing the compiler knows that this is a deduction guide and which class template it is connected to, so it should be able to parse the rest exactly as if it was a trailing return type.

I think I agree. We should allow this to work:

    template<class F> receiver(F&&) -> detail::corresponding_type<receiver, F>;

One question would be what happens if the typedef expands to something
that is not a valid specialization of `receiver` — e.g. what if it's a
specialization of a different template, or not-a-template, or
ill-formed? Is that something like a substitution failure?

> I can't figure out a workaround that allows me to create a receiver like this given this limitation...

The Right Answer is to do what `std::function` and `std::function_ref`
do: instead of `receiver<Ps...>` you should just use
`receiver<void(Ps...)>`. Then it's easy to write

    template<class F> receiver(F&&) -> receiver< detail::corresponding_sig<F> >;

    template<class F> receiver_impl(F&&) -> receiver_impl<
detail::corresponding_sig<F> >;
    template<class... Ps> using receiver = receiver_impl<void(Ps...)>;
but I think this doesn't work in C++20; I think you need "CTAD for
alias templates" before this will have even a hint of working, and
maybe not even then.

By the way, another fantasy feature that would solve your problem is
if a metafunction could return a first-class pack. Then you could
write something like

    template<class F> receiver(F&&) -> receiver<
detail::corresponding_template_args<receiver, F>... >;

But of course that doesn't help you today.

> PS: I just found on GodBolt an experimental Clang version called NDSMI which allows auto and CTAD on data members. Does anyone know who did this and if it has a corresponding proposal?

I vaguely recollect that the auto-NSDMI branch on Godbolt was done by
Corentin Jabot.
Yep. Googling "godbolt github auto nsdmi" finds:


Received on 2021-02-20 10:32:17