C++ Logo

std-proposals

Advanced search

Re: Video Intro to WG21/D2288 C++ Designated Arguments

From: Hani Deek <hani_deek_at_[hidden]>
Date: Tue, 23 Nov 2021 18:58:09 +0000
> template <typename T> struct Args { T x; int y = 0; };
> template <typename T> void f(Args<T> args);
> f({.x=5}); // nope

Yes that code won't work, but what is the problem here? The problem is a limitation of template argument deduction. This is a problem whose scope is larger than the scope of our discussion. It will be great if someone proposes a general solution for this problem, but for the purposes of our discussion, we can propose some limited solution. For example, we can add a rule to the rules of template argument deduction which says that if the parameter list of a function template contains a definition of an aggregate class type, then the data members of that type are treated as if they were independent members of the parameter list for the purposes of template argument deduction.

For example, if the compiler finds the following template declaration.

template<typename T0, typename T1>
void f(T0, struct { int x; T1 y; });

Then the compiler converts the template into the following temporary form, by converting the aggregate type into separate parameters.

template<typename T0, typename T1>
void f(T0, int x, T1 y);

The initializer of the aggregate parameter is likewise converted into separate arguments, then every argument is matched with the corresponding parameter and deduction goes as usual. If the template arguments are successfully deduced, they are substituted into the original template.

I believe that is a simple solution to this issue, but it is not great because it is an ad hoc solution. It will be better if we can have a more general solution.

In any case, the original proposal does nothing to address this old problem of template argument deduction.

> Indeed, the only way to call such a function through forwarding is to
> explicitly construct a parameter of the proper type, which requires
> being able to *name* the type, which you can't do if you declared the
> parameter in the function declaration.

I don't think I understand this issue.

Given the following template

template<typename T0, typename T1>
void f(struct { T0 &&a; T1 &&b; });

You can forward the arguments as usual, e.g.

std::forward<T0>(a), std::forward<T1>(b)

Received on 2021-11-23 12:58:12