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

[temp.arg.explicit] doesn't allow converting arguments if they deduced template parameters in non-deduced context #5115

Open
leni536 opened this issue Nov 19, 2021 · 2 comments

Comments

@leni536
Copy link

leni536 commented Nov 19, 2021

Observation

draft/source/templates.tex

Lines 6895 to 6899 in 02f9bb5

Implicit conversions\iref{conv} will be performed on a function argument
to convert it to the type of the corresponding function parameter if
the parameter type contains no
\grammarterm{template-parameter}{s}
that participate in template argument deduction.

This wording does not allow conversion in the argument if the parameter contains template parameters in non-deduced context, but they are otherwise deduced.

Expectation

The wording to allow conversion if all the template parameters in the function parameter are explicitly specified or appear in non-deduced context.

Examples

Example 1

#include <type_traits>

template <typename T>
struct A {
    A();
    A(T);
};

template <typename T>
void bar(A<std::type_identity_t<T>>, A<T>);

void foo() {
    bar(42, A<int>{}); // conversion from int to A<int> in the first argument

In the example the first parameter contains the template parameter T, and T participates in template argument deduction. So the wording doesn't enable implicit conversion in that argument.

Compilers seem to agree that conversion is allowed there: https://godbolt.org/z/aPdK64zeG

Example 2

There is a similar example in the standard too:

draft/source/templates.tex

Lines 8481 to 8498 in 02f9bb5

\begin{note}
Template parameters do not participate in template argument deduction if
they are used only in non-deduced contexts.
For example,
\begin{codeblock}
template<int i, typename T>
T deduce(typename A<T>::X x, // \tcode{T} is not deduced here
T t, // but \tcode{T} is deduced here
typename B<i>::Y y); // \tcode{i} is not deduced here
A<int> a;
B<77> b;
int x = deduce<77>(a.xm, 62, b.ym);
// \tcode{T} deduced as \tcode{int}; \tcode{a.xm} must be convertible to \tcode{A<int>::X}
// \tcode{i} is explicitly specified to be \tcode{77}; \tcode{b.ym} must be convertible to \tcode{B<77>::Y}
\end{codeblock}
\end{note}

Here the conversion happens in the first argument.

Suggestion

I suggest to replace the wording with the following:

Implicit conversions ([conv]) will be performed on a function argument to convert it to the type of the corresponding function parameter if all the template-parameters it contains are explicitly specified or appear in non-deduced context.

@jensmaurer
Copy link
Member

I think the suggested wording doesn't say the right thing yet, because "appear in a non-deduced context" doesn't say whether "for this function parameter only" or "anywhere in the function parameter list" and whether it's "only" or "also".

@leni536
Copy link
Author

leni536 commented Nov 20, 2021

Yes, I agree. I suggest the following wording then:

Implicit conversions ([conv]) will be performed on a function argument to convert it to the type of the corresponding function parameter if all the template-parameters it contains are explicitly specified or appear only in non-deduced contexts within this function parameter.

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

2 participants