C++ 为什么在VisualStudio2008/2010中不需要typename?

C++ 为什么在VisualStudio2008/2010中不需要typename?,c++,visual-studio,typename,C++,Visual Studio,Typename,在中,询问者具有以下功能: template<typename ITER> bool nextPermutation(ITER start, ITER end) { return nextPermutation(start, end, std::iterator_traits<ITER>::iterator_category()); } 模板 bool下一个术语(ITER开始、ITER结束) { 返回nextpermutate(开始、结束、std::iterat

在中,询问者具有以下功能:

template<typename ITER>
bool nextPermutation(ITER start, ITER end)
{
    return nextPermutation(start, end, std::iterator_traits<ITER>::iterator_category());
}
模板
bool下一个术语(ITER开始、ITER结束)
{
返回nextpermutate(开始、结束、std::iterator_traits::iterator_category());
}
为什么在
std::iterator_traits
之前不需要
typename
?我认为嵌套类型的模板需要它,如果模板依赖于模板参数本身?GCC似乎支持我的想法,因为它不在和下编译,需要
typename
。即便如此,在VisualStudio2008和2010下,它仍然可以正常编译。
这只是我不知道的另一个Visual Studio扩展/bug吗?

或者,实际上可以推断出,
迭代器_category
是一个类型还是一个函数,因为它后面有一对括号
()
?(见Dead Mig.的消息)所以这可能是GCC中的一个bug吗?< /P> < P> VisualC++是众所周知的,不完全支持两阶段查找,这是为什么首先需要代码> >类型名称< />代码的根本原因。如果编译器不完全支持这一点,那么在实例化模板之前,它可能不会完全解析模板,到那时它“知道”了
std::iterator\u traits::iterator\u category
是一个类型。显然,这一缺陷延伸至VC10


说到这一点,我相信GCC而不是VC

MSVC没有实现延迟解析方案吗?在这种方案中,编译器不依赖于
typename
。它只是将所有标记存储在模板定义的大括号之间,当模板被实例化时,它会解析这些标记。因为它知道什么是类型,什么不是类型,所以它将在没有
typename
的情况下工作

但是,如果编译器在实例化模板时没有诊断缺少的
typename
,那么它就是不一致的

或者,因为迭代器_类别后面跟一对括号(),所以实际上可以推断它是一个类型还是一个函数

重要的是名称是否依赖和限定。模板是否能够推断名称始终是一个类型并不重要。但这可能会影响缺少
typename
s的错误消息的质量


FWIW,不,不可能从语言层面推断出任何关于迭代器类别的信息

除了列出的选项(构造函数和函数),
iterator_category
可以是定义运算符()类型的静态成员变量。@Sjoerd:或函数指针。请注意,所需的诊断仅允许作为警告。因此,只要编译器发出至少一个警告,就允许“编译得很好”。第二,默认情况下,可以关闭警告。我知道的所有编译器都需要一个标志或选项,以便尽可能紧跟C++标准:升级编译器时,大多数客户不希望他们的旧代码出现新的警告/错误,因此向后兼容性迫使编译器编写者将新错误隐藏在附加选项后面。@Sjoerd:标准总是只提到“诊断”。这可能是错误或警告,两者都可以。@sbi我相信您和Johannes知道这一点,但这不是常识。答案非常完整,但我将接受@Johannes的答案,因为它解释了更多关于后期解析的内容+1尽管如此。:)