2016-10-07 20:32 GMT+02:00 Richard Smith <
ric...@metafoo.co.uk>:
> On Fri, Oct 7, 2016 at 8:28 AM, 'Johannes Schaub' via ISO C++ Standard -
> Discussion <
std-dis...@isocpp.org> wrote:
>>
>> Given this typedef
>>
>> template<typename T>
>> class A { };
>>
>> typedef A<int> SomeInt;
>>
>> GCC allows to explicitly instantiate it by using the injected class name
>>
>> template class SomeInt::A;
>>
>> It is clear that this is ill-formed by
>>
>> "If the explicit instantiation is for a class or member class, the
>> elaborated-type-specifier in the declaration shall include a
>> simple-template-id."
>>
>> However, this requirement seems ridiculous. The following appears to
>> satisfy it, seemingly making it valid C++. Clang still rejects it and
>> GCC still accepts
>>
>> template<typename T> using alias = T;
>> template class alias<SomeInt>::A;
>>
>> I am not sure whether I can make sense of the requirement, and why
>> Clang still rejects the code.
>
>
> Clang is not rejecting it due to the rule you quote; enforcement of that
> weird rule is relaxed by default and only enabled under -pedantic. Instead,
> the issue is that Clang is just not expecting to be told to explicitly
> instantiate the injected-class-name of a class template.
>
Ah I see. I do not find support for that behavior of clang in the spec, though.
> I think the more interesting question is whether GCC is correct to accept
> "template class SomeInt::A;". [temp.local]/1 says:
>
> "Like normal (non-template) classes, class templates have an
> injected-class-name (Clause 9). The injected-class-name can be used as a
> template-name or a type-name. When it is used with a template-argument-list,
> as a template-argument for a template template-parameter, or as the final
> identifier in the elaborated-type-specifier of a friend class template
> declaration, it refers to the class template itself. Otherwise, it is
> equivalent to the template-name followed by the template-parameters of the
> class template enclosed in <>."
>
> If SomeInt::A is truly equivalent to SomeInt::A<int>, does that mean that
> SomeInt::A is considered to include a simple-template-id? I'd be inclined to
> say no, since the simple-template-id rule is clearly concerned with the
> syntactic form of the declaration and not the semantics, but this doesn't
> seem very clear.
>
About the ambiguity, I agree and I think that it should not be
considered to be equivalent to a simple-template-id. Equally I think
that it's not really clear. For example,
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2143
clarified indirectly that the injected class name is not considered to
be a simple-template-id even if used as a type. On the other side, I
remember that I sent in a DR about the same issue, and it was rejected
on the basis that the injected class name is equivalent to a
simple-template-id in the relevant case.
The description, "equivalent to a <non-terminal> followed by the
<non-terminals> enclosed by <tokens>", sounds rather synactic though.
So I understand that there can be different opinions with regard to
this text.
If we use the "alias" trick of above however, the question whether GCC
is correct or not is correctly answered as "correct", right? Then
there does exist a simple-template-id in the elaborate type specifier.