Consider the following example
template <typename A> struct S
{
A a;
void foo() {}
};
template <typename T> void bar()
{
S<void> *p = 0;
}
template <typename T> void baz()
{
S<void>{}.foo();
}
template <typename T> void qux()
{
S<void> s{};
}
int main()
{
}
Function templates bar
, baz
and qux
are deliberately left non-instantiated.
The definition of baz
fails to compile in GCC and Clang for "obvious" reason - S<void>
is an invalid specialization of S
. However, which language rule is working in this case?
On the one hand,
S<void>
does not depend on template parameters ofbaz
, member access requires it to be complete, which triggers instantiation ofS<void>
, which fails. Diagnostic is required.On the other hand we have the blanket rule of "if no valid specialization can be generated for a non-instantiated template, the code is ill-formed". This makes the definition of
baz
ill-formed. However, no diagnostic is required.
More specifically, am I correct in my assumption (as expressed in #1) that the above reference to S<void>
from non-instantiated baz
requires instantiation of S<void>
? The assumption is supported by the fact that both compilers happily accept the definition of bar
, which does not instantiate S<void>
.
However, the aforementioned compilers differ in their treatment of qux
- Clang complains, while GCC accepts it without any complaints. Is this a bug in one of the compilers? Is diagnostic required in this case? Or am I wrong in my assumption that #1 is at work here? If #2 is the basis for the diagnostic, then the difference between the compilers is acceptable.