Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[over.match.class.deduct] CTAD from inherited constructors handling of template parameters with default arguments #627

Open
antangelo opened this issue Oct 23, 2024 · 0 comments

Comments

@antangelo
Copy link

Full name of submitter (unless configured in github; will be published with the issue): Antonio A

Reference (section label): [over.match.class.deduct]

Link to reflector thread (if any):

Issue description:

Consider the following example:

template<typename T>
struct Base {
    Base(int);
};

template<typename T = int, typename V = float>
struct Derived : public Base<T> {
    using Base<T>::Base;
};

Derived d(1);

To form deduction guides from the inherited constructors of Base for Derived, the standard has the following text on the return type:

... with the return type R of each guide replaced with typename CC<R>​::​type given a class template
template <typename> class CC;
whose primary template is not defined and with a single partial specialization whose template parameter list is that of A ...

Let C represent Derived, then the template parameter list of the alias A is that of C, and the parameter list of A contains parameters with default arguments. No partial specialization's template parameter list may contain default arguments as per [temp.spec.partial.general]p9.3. Thus, this construction as it appears in the standard is invalid in this case.

Moreover, it is insufficient to strip default arguments from the parameter list of CC because it is possible to have parameters that do not appear in the base (in the above example, V) and those parameters will not be deducible in the partial specialization.

Suggested resolution:

The specialization should have the template parameter list of C, but with the parameters rewritten such that:

  1. If a parameter has a default argument, and the parameter is not in the parameter list of B, then it is substituted by its default argument.
  2. If a parameter has a default argument, and the parameter is present in the parameter list of B, then it is replaced by the same parameter, but with the default argument removed.
  3. Parameters with no default argument remain unchanged, other than being rewritten with any changes from the above.

The alias template should have the template parameter list of C, but with the parameters rewritten such that:

  1. If a parameter has a default argument, and the parameter is not in the parameter list of B, then it is substituted by its default argument.
  2. Other parameters, including both those without default arguments and those with default arguments that appear in the parameter list of B remain unchanged, other than being rewritten with any changes from the above. In this case, it is necessary to preserve the default arguments if there are any, as that information is necessary for deduction.

With this suggested resolution, the partial specialization will not have any parameters with default arguments, default arguments for parameters not in the parameter list of B are deduced up front (as they cannot be influenced by B) and default arguments for parameters in the parameter list of B retain their default argument in A, allowing them to be deduced correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant