我正在两个编译器(Clang on Xcode v5.0.2和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
关键字 not 时,错误为:
使用'template'关键字将'InnerBase'视为依赖模板名称
对于Visual Studio,当包含 template
关键字 is 时,错误为:
'Base :: InnerBase':使用类模板需要模板参数列表
我查看了有关 template
关键字使用规则的各种其他StackOverflow问题(例如,Where and why do I have to put the "template" and "typename" keywords?) . 但是,看看这个和其他类似的问题,并没有让我有信心声称一个编译器正确地实现了C 11而另一个编译器没有 .
(请注意,Clang 's error makes sense to me, while the VS error doesn' t对我来说很有意义,因为我似乎包含了模板参数列表 . )
在这种情况下哪个编译器是正确的?是否应在上面的示例代码中包含 template
关键字(符合C 11标准)?
(可能我没有正确设置编译器设置以在一种情况下使用C 11 - 在这种情况下,我的问题仍然存在:上面代码的哪个版本是正确的C 11代码?)
2 回答
似乎相关条款是14.2(temp.names)第4段:
我认为这需要
template
. 跟进DyP 's comment, it seems certainly wrong to reject the keyword even if it isn' t(同一条款第5段):Clang是正确的,
Base<T>
依赖于模板参数 . 这是Visual C未实现模板的两阶段名称查找的另一个症状 .