C++ 是";typename";C+中允许/要求+;11使用声明?
以下代码在g++和clang中正确编译:C++ 是";typename";C+中允许/要求+;11使用声明?,c++,c++11,typename,using-declaration,C++,C++11,Typename,Using Declaration,以下代码在g++和clang中正确编译: template<typename T> struct foo { class iterator; using bar = foo::iterator; }; int main() {} 然后三个编译器都成功地编译了它。原始版本正确吗?(即,这是MSVC错误还是gcc/clang扩展)[temp.res]/p3: 当限定id意指的类型不是 当前实例化(14.6.2.1)的成员及其 嵌套名称说明符是指依赖类型,它的前缀应为关
template<typename T>
struct foo
{
class iterator;
using bar = foo::iterator;
};
int main() {}
然后三个编译器都成功地编译了它。原始版本正确吗?(即,这是MSVC错误还是gcc/clang扩展)[temp.res]/p3:
当限定id意指的类型不是
当前实例化(14.6.2.1)的成员及其
嵌套名称说明符是指依赖类型,它的前缀应为关键字typename
,形成一个typename说明符
[临时部门类型]/p1:
名称引用当前实例化(如果是)
- 在类模板的定义中,类模板的嵌套类、类模板的成员或嵌套类的成员 对于类模板,类的注入类名(第9条) 模板或嵌套类
- [……]
- 一种非限定名称,在查找时,它至少引用当前实例化类或非依赖类的一个成员 其基类。[注意:这只能在查找 类模板定义所包含的作用域中的名称。-结束 注]
- 一种限定id,其中嵌套的名称说明符引用当前实例化,并且在查找时至少引用一个实例 当前实例化或非依赖的类的成员 其基类。[注:如果未找到此类成员,以及 当前实例化有任何依赖的基类,然后 限定id是未知专业化的成员;请参见下文。 -[完注]
- [……]
foo
是当前的实例化foo::iterator
是一个限定id,其中嵌套的名称说明符(foo::
)引用当前实例化,当查找时,“引用作为当前实例化或其非依赖基类的类的至少一个成员”;因此,它是当前实例化的成员。因此,[temp.res]/p3不适用,不需要typename
。您仍然可以添加一个-或直接使用迭代器不合格。来自标准:
14.6.2.1相关类型[临时部门类型]
1名称是指当前实例化(如果是)
__在类模板、类模板的嵌套类、类模板的成员或类模板的嵌套类的成员的定义中,类模板的注入类名称(第9条)
或嵌套类
名称foo
引用了当前的实例化,这是显而易见的
由于iterator
在模板的定义中声明为嵌套类,iterator
引用了foo
当前实例化中的名称foo::iterator
与iterator
相同
using bar = foo::iterator;
以及
using bar = iterator;
应该有用
在我看来,您似乎遇到了MSVC缺陷。允许,是的。必选,否。foo::iterator
指定当前实例化的一个成员。我认为这可以做到,您发现它更快,+1:)
using bar = foo::iterator;
using bar = iterator;