Reputation: 20726
Suppose i have the following code:
template <template <typename> class T>
class A {};
template <typename T>
class B
{
A<B> instance;
};
int main()
{
B<int> instance;
}
gcc 4.7.2 and gcc 4.8.0 compiles this code ok, while icc 13.0.1 and clang 3.2 gave me an error (clang require ::B instead of B, while icc also require whitespace after < in template instantiaion).
Who's right?
I found the thread about it (Template class that refers to itself as a template template parameter?), but i can't understand 14.6.1/2 of the standard and also saw LLVM bug 14350 (http://www.mail-archive.com/[email protected]/msg21095.html). So, clang and intel wrong here?
Upvotes: 0
Views: 72
Reputation: 241671
14.6.1 says:
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.
The "injected-class-name" is the name of the class template (B
) "injected" into the scope of the class. In other words, it refers to the use of the unqualified name B
within the definition of the class B
. If you use that name in a context where a template name is required: i.e., with explicit template arguments (B<int>
) or as a template argument for a template which takes a template template parameter (A<B>
), it should refer to the template itself.
So, gcc is right.
Also, in C++11, you should not need a space after the <
in <::B>
. According to section 2.5, paragraph 3, when dividing the input stream into tokens:
if the next three characters are
<::
and the subsequent character is neither:
nor>
, the<
is treated as a preprocessor token by itself and not as the first character of the alternative token<:
. (<:
is another way of writing[
.)
Upvotes: 1