Clang (OS X) requires the keyword "template" in a specific nested declaration, while VS forbids it

I am writing a cross-platform application in two compilers (Clang on Xcode v5.0.2 and Visual Studio 2012 Update 4), and I came across a script in which two compilers do not agree with the required syntax for using the template keyword in a nested declaration.

Here is the code (reduced to an easily reproducible test case):

 template<typename T> struct Base { template<typename U> struct InnerBase {}; }; template<typename T, typename U> struct Derived : public Base<T> { // the "template" keyword is REQUIRED in Clang/OSX struct InnerDerived : public Base<T>::template InnerBase<U> {}; // the "template" keyword is FORBIDDEN in Visual Studio 2012 struct InnerDerived : public Base<T>::InnerBase<U> {}; }; int main() { Derived<int, int>::InnerDerived foo; } 

As already noted, the two compilers do not agree with the use of the keyword "template".

For Clang, when the template keyword contains no , the error is:

Use the keyword 'template' to treat 'InnerBase' as a dependent template name

For Visual Studio, when template keyword is enabled , mistake:

'Base :: InnerBase': using a template template requires an argument list template

I looked at various StackOverflow questions regarding the rules for using the template keyword (for example, Where and why do I need to put the template “keywords”, etc.). However, looking at this and other similar questions, I’m not sure if there is one compiler implements C ++ 11 correctly and the other doesn't.

(Note that the Clang error makes sense to me, while the VS error doesn't make much sense to me because it seems like I'm including a list of template arguments.)

Which compiler is right in this case? If the template keyword should be included or not, in the above code example (for C ++ 11 compliance)?

(Perhaps I did not set the correct compiler settings to use C ++ 11 in one or the other case - in this case, my question still stands: which version of the code above is correct with C ++ 11?)

+7
c ++ c ++ 11 templates clang visual-studio-2012
source share
2 answers

The corresponding sentence seems to be clause 14.2 (temp.names):

When the name of the custom template template appears after . or -> in a postfix expression or after a sub-name specifier in an identifier with qualification, and the postfix-expression object expression is of type -dependent or specified by sub-name-identifier in identified-id refers to the dependent type, but the name is not a member of the current instance (14.6 .2.1), the member template name must be prefixed with the template keyword.

I think that says template is required. After the DyP comment, it seems wrong to reject the keyword, even if it is not required (paragraph 5 of the same sentence):

The name prefixed with the template keyword must be the template identifier or the name must refer to the class template. [Note. The template keyword may not apply to class template elements without templates. -end note] [Note: as with the typename prefix, the template prefix is ​​allowed in cases where this is not strictly necessary; those. when the nested name specifier or expression to the left of -> or . does not depend on the template parameter or usage is not displayed in the template area.-end note].

+7
source share

Clang is correct, Base<T> depends on the template parameter. This is another Visual C ++ symptom that does not implement two-phase name lookups for templates.

+5
source share

All Articles