我正在使用两个编译器(Xcode v5.0.2 上的 Clang 和 Visual Studio 2012 Update 4)编写一个跨平台应用程序,我遇到了两个编译器不同意使用所需语法的场景嵌套声明中的 template
关键字。
这是代码(归结为一个易于重现的测试用例):
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;
}
如前所述,两个编译器不同意"template"关键字的使用。
对于Clang,当不包含template
关键字时,错误是:
Use 'template' keyword to treat 'InnerBase' as a dependent template name
对于 Visual Studio,当 template
关键字被包含时,错误是:
'Base::InnerBase' : use of class template requires template argument list
我查看了有关 template
关键字(例如,Where and why do I have to put the "template" and "typename" keywords?)的使用规则的各种其他 StackOverflow 问题。但是,看看这个问题和其他类似问题,并没有让我有信心声称一个编译器正确实现了 C++11 而另一个没有。
(请注意,Clang 的错误对我来说很有意义,而 VS 错误对我来说没有多大意义,因为看起来我包括了模板参数列表。)
在这种情况下哪个编译器是正确的?上面的示例代码中是否应该包含 template
关键字(为了符合 C++11)?
(可能我没有正确设置编译器设置以在一种或另一种情况下使用 C++11 - 在这种情况下,我的问题仍然存在:上面哪个版本的代码是正确的 C++11 代码?)
最佳答案
相关条款似乎是 14.2 (temp.names) paragraph 4:
When the name of a member template specialization appears after
.
or->
in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keywordtemplate
.
我认为那是说 template
是必需的。跟进 DyP的评论,拒绝关键字似乎肯定是错误的,即使它不是必需的(同一条款的第 5 段):
A name prefixed by the keyword
template
shall be a template-id or the name shall refer to a class template. [Note: The keywordtemplate
may not be applied to non-template members of class templates. —end note] [Note: As is the case with thetypename
prefix, thetemplate
prefix is allowed in cases where it is not strictly necessary; i.e., when the nested-name-specifier or the expression on the left of the->
or.
is not dependent on a template-parameter, or the use does not appear in the scope of a template.—end note].
关于c++ - Clang (OS X) 在特定的嵌套声明中需要 "template"关键字,而 VS 禁止它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20847637/