I was writing a rather simple example to clarify(better understand) the concept of non type template parameters. The example is shown below. To my surprise, the given example compiles with MSVC and Clang but fails to compile with GCC(for both C++14 & C++17).
template<typename T, T a>
void f()
{
decltype(a) p; //is this valid given the call expression f<const int, 0>() below
}
int main()
{
f<const int,0>();
}
Which compiler is right here according to the standard.
To my current understanding of templates, this is what should happen:
Point 1
From temp.param#5:
On the first glance it seems that when applied to the given snippet,
a
should beint
instead 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
a
isconst int
instead ofint
. This would suggest that GCC is correct in rejecting the code since we should provide an initializer for theconst
variable namedp
.Note that i may be wrong in interpreting [temp.param#5] above.
Point 2
But from temp.param#6:
Moreover, from expr#6:
When applying temp.param#6 and expr#6 to the given snippet, it means that
a
(a prvalue) will finally be of typeint
instead ofconst int
. That is, this suggest that MSVC and Clang are correct in accepting the code, sincep
is a non-constint
.So, given the above analysis, my thinking is that the code is valid and so msvc and clang are correct in accepting it.