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

Viewed 2654

I am writing a cross-platform application in two compilers (Clang on Xcode v5.0.2, and Visual Studio 2012 Update 4) and I have run into a scenario in which the two compilers disagree about the required syntax for the use of the template keyword in a nested declaration.

Here is the code (boiled down 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 noted, the two compilers disagree about the use of the "template" keyword.

For Clang, when the template keyword is not included, the error is:

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

For Visual Studio, when the template keyword is included, the error is:

'Base::InnerBase' : use of class template requires template argument list

I have looked at various other StackOverflow questions regarding the rules for use of the template keyword (for example, Where and why do I have to put the "template" and "typename" keywords?). However, looking at this, and other similar questions, does not give me confidence in claiming that one compiler is correctly implementing C++11 and that the other is not.

(Note that Clang's error makes sense to me, while the VS error doesn't make much sense to me because it seems that I am including the template argument list.)

Which compiler is correct in this case? Should the template keyword be included, or not, in the sample code above (for C++11 compliance)?

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

2 Answers
Related