Clang(OS X)要求在特定嵌套声明中"template"关键字,而VS禁止它
Clang (OS X) requires "template" keyword in a particular nested declaration, while VS forbids it
我正在用两个编译器(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
关键字不包括时,错误为:
使用"template"关键字将"InnerBase"视为依赖模板名称
对于Visual Studio,当包含template
关键字时,错误为:
'Base::InnerBase':使用类模板需要模板参数列表
我已经研究了关于template
关键字使用规则的其他各种StackOverflow问题(例如,我必须将"template"answers"typename"关键字放在哪里以及为什么放?)。然而,考虑到这一点和其他类似的问题,我并没有信心声称一个编译器正确地实现了C++11,而另一个则不是。
(请注意,Clang的错误对我来说有意义,而VS错误对我没有多大意义,因为我似乎包括模板参数列表。)
在这种情况下,哪个编译器是正确的?template
关键字是否应该包含在上面的示例代码中(对于C++11的遵从性)?
(可能我没有正确设置编译器设置,在一种或另一种情况下使用C++11——在这种情况下,我的问题仍然存在:上面的代码的哪个版本是正确的C++11代码?)
似乎相关条款是14.2(临时名称)第4段:
当成员模板专用化的名称出现在后缀表达式中的
.
或->
之后,或出现在限定id中的嵌套名称说明符之后,并且后缀表达式的对象表达式是类型依赖的,或限定id中嵌套名称说明符指代依赖类型,但名称不是当前实例化的成员时(14.6.2.1),成员模板名称必须以关键字CCD_ 8作为前缀。
我认为这说明template
是必需的。根据DyP的评论,即使不需要也拒绝关键词似乎是错误的(同一条款的第5段):
以关键字
template
为前缀的名称应为模板id,或者该名称应引用类模板。[注意:关键字template
不能应用于类模板的非模板成员。--结束注释][注意:与typename
前缀的情况一样,template
前缀在非严格必要的情况下是允许的;即,当嵌套的名称说明符或->
或.
左侧的表达式不依赖于模板参数,或者该用法不出现在模板的范围内时。--结束注释]。
Clang是正确的,Base<T>
依赖于模板参数。这是Visual C++没有为模板实现两阶段名称查找的另一个症状。
- Visual Studio 2015:Extern "C" 和 "export" 关键字
- 表示"accepting anything for this template argument" C++概念的通配符
- C++中的"inline"关键字
- 如何确保C++函数在定义之前声明(如override关键字)
- 传递给std::function template的template参数究竟代表什么
- 在template中使用std::variant的template函数
- 谷歌模拟和覆盖关键字
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- 为什么"delete"关键字不删除节点?
- 在 c++ 中正确定义"this"关键字?
- 这个额外的关键字在这个 c++ 类声明中是什么意思?
- C++ template for QList
- 在 typedef 内部使用 const 关键字和在 typedef 外部使用 const 关键字之间有区别吗?
- C++ - 为什么这里需要'template'关键字?
- "template"关键字限定符是否会导致代码成功编译,但不同?
- Clang(OS X)要求在特定嵌套声明中"template"关键字,而VS禁止它
- 再次强调typename和template关键字
- 函数声明中template关键字的含义