Clang ++ - handle the class name of a template template in a class

It seems that clang ++ (I tried clang 3.2) saw the class name of the template as an instance of the class, not a template for any occurrence within the class. For example, the following codes

template <template <class> class T> class A {}; template <typename T> class B { A<B> member; // ^---- clang++ treats B as an instantiated class // but I want it to be a template here // this code could compile in g++ }; int main() { B<int> b; return 0; } 

What should I do to compile this?

+4
source share
2 answers

C ++ 03

Allowing B in this way (called the name incied-class-name, an implicitly declared member of each class, including template instances) is for convenience. I have never seen it like that!

To work, qualify the name by adding :: in front of it (and, if necessary, the namespace name).

 template <typename T> class B { A< ::B> member; // whitespace required to prevent digraph; see comments }; 

C ++ 11

C ++ 11 ยง14.6.1 / 1 indicates (emphasis mine)

Like regular (non-template) classes, class templates have a name with the class introduced (section 9). The name of the entered class can be used as a template name or type name. When it is used with a template-argument-list, as a template argument for a template-template-template or as a final identifier in a specified specifier of the type declaration template of a friend's class, refers to the class template itself. Otherwise, this is equivalent to the template name, followed by the template parameters of the class template enclosed in <>.

Therefore, if this problem occurs in C ++ 11, this is a compiler error. Workaround as above.

Note. For comparison, the corresponding paragraph in C ++ 03

Like ordinary (non-template) classes, class templates have a name with the class introduced (item 9). The name of the introduced class can be used with or without a list of argument templates. When used without a list of argument templates, it is equivalent to the name of the entered class, followed by the template parameters of the class template enclosed in <>. When used with an argument-list-template, it refers to the specified specialization of the class template, which may be the current specialization or another specialization.

As you can see, there is already one special case that allows an identifier to be a class or a template, depending on whether it appears in the name of the template. They just added a couple more cases.

+3
source

This is inappropriate behavior with C ++ 11 because C ++ 11 says that the entered class name (which is a declaration declared automatically inside the class body) is a template when it is passed to the template template parameter. So your code should crash only in a C ++ 03 implementation.

However, now there is no need to open an error report. I already did it back.

+1
source

All Articles