Full name of submitter: Anoop Rana
Reference (section label): temp.param
Link to reflector thread (if any): https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125300
Issue description: Consider the following program that shows implementation divergence. GCC and EDG accept the program while Clang and MSVC reject it. This seems ill-formed to me for the reason(s) given below. I reported the bug at gcc where the maintainer seems to say that there may be a defect here in the standard.
//----------------------v--->i named the parameter for explanation purposes
template <typename T, T p>
struct A { };
template <typename T, T t>
void f(A<T, t>) {
}
int main() {
f(A<const int, 0>{});
}
Here is my explaination of why this ought to be ill-formed.
Step 1
Here we consider what happens for the expression A<const int, 0>{}.
From temp.param#5:
The top-level cv-qualifiers on the template-parameter are ignored when determining its type.
On the first glance it seems that when applied to the given snippet, the non-type template parameter named p should be int instead of const int.
But note the emphasis on the highlighted part in the above quoted statement. In particular, my interpretation of this(the phrase "when determining") is that the top-level cv-qualifiers are dropped when deducing the template parameter and so not when the template arguments are explicitly specified.
And since in my given snippet, we are explicitly specifying the template argument, there is no template argument deduction(TAD) here. Thus, the dropping of the top-level cv-qualifiers due to the above quoted temp.param#5 does not happen. Meaning the type of p is const int instead of int.
Note that i may be wrong in interpreting [temp.param#5] above.
But before further analysis, from temp.param#6:
A non-type non-reference template-parameter is a prvalue. It shall not be assigned to or in any other way have its value changed.
Moreover, from expr#6:
If a prvalue initially has the type “cv T”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
When applying temp.param#6 and expr#6 to the given snippet, it means that p(a prvalue) will finally be of type int instead of const int.
Thus, the non-type template parameter p is of type int.
Step 2
Next, we consider what happens for the call expression f(A<const int, 0>{}).
Now currently we have a prvalue A<const int, 0> whose first type parameter T is const int while the second non-type template parameter p is of type int. Thus, for the function template f<> the first template type parameter T is deduced to be const int while the type of non-type template parameter t is deduced to be int. Thus there is a conflict between the type of T and hence the mentioned error saying:
<source>:7:6: note: candidate template ignored: deduced conflicting types for parameter 'T' ('const int' vs. 'int')
void f(A<T, t>) {
^
So, kindly clarify what is the intended behavior here and ammend the wording accordingly(if necessary) so that gcc etc can correct their compiler as currently they're not sure what is the problem here.
Full name of submitter: Anoop Rana
Reference (section label): temp.param
Link to reflector thread (if any): https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125300
Issue description: Consider the following program that shows implementation divergence. GCC and EDG accept the program while Clang and MSVC reject it. This seems ill-formed to me for the reason(s) given below. I reported the bug at gcc where the maintainer seems to say that there may be a defect here in the standard.
Here is my explaination of why this ought to be ill-formed.
Step 1
Here we consider what happens for the expression
A<const int, 0>{}.From temp.param#5:
On the first glance it seems that when applied to the given snippet, the non-type template parameter named
pshould beintinstead ofconst int.But note the emphasis on the highlighted part in the above quoted statement. In particular, my interpretation of this(the phrase "when determining") is that the top-level cv-qualifiers are dropped when deducing the template parameter and so not when the template arguments are explicitly specified.
And since in my given snippet, we are explicitly specifying the template argument, there is no template argument deduction(TAD) here. Thus, the dropping of the top-level cv-qualifiers due to the above quoted temp.param#5 does not happen. Meaning the type of
pisconst intinstead ofint.Note that i may be wrong in interpreting [temp.param#5] above.
But before further analysis, from temp.param#6:
Moreover, from expr#6:
When applying temp.param#6 and expr#6 to the given snippet, it means that
p(a prvalue) will finally be of typeintinstead ofconst int.Thus, the non-type template parameter
pis of typeint.Step 2
Next, we consider what happens for the call expression
f(A<const int, 0>{}).Now currently we have a prvalue
A<const int, 0>whose first type parameterTisconst intwhile the second non-type template parameterpis of typeint. Thus, for the function templatef<>the first template type parameterTis deduced to beconst intwhile the type of non-type template parametertis deduced to beint. Thus there is a conflict between the type ofTand hence the mentioned error saying:So, kindly clarify what is the intended behavior here and ammend the wording accordingly(if necessary) so that gcc etc can correct their compiler as currently they're not sure what is the problem here.