为什么Visual Studio 2008/2010中需要typename _not_?

Xeo*_*Xeo 6 c++ typename visual-studio

这个问题中,提问者具有以下功能:

template<typename ITER>
bool nextPermutation(ITER start, ITER end)
{
    return nextPermutation(start, end, std::iterator_traits<ITER>::iterator_category());
}
Run Code Online (Sandbox Code Playgroud)

为什么typename不需要之前std::iterator_traits?我认为模板的嵌套类型需要它,如果模板依赖于模板参数本身?GCC似乎支持我的想法,因为它不能在4.3.44.5.1下编译,要求a typename.即便如此,它仍然在Visual Studio 2008和2010下编译得很好.
这只是另一个我不知道的Visual Studio扩展/错误吗?
或者它实际上可以推断出这iterator_category是一个类型还是一个函数,因为它后跟一对括号()?(请参阅@ DeadGM 从此处开始的消息.)这可能实际上是GCC中的一个错误吗?

sbi*_*sbi 12

众所周知,Visual C++不(完全)支持两阶段查找,这是为什么typename首先需要的根本原因.如果编译器不完全支持它,它可能无法在实例化之前完全解析模板,这时它"知道"这std::iterator_traits<ITER>::iterator_category是一种类型.显然,这种缺陷延伸到VC10.

谈到typename,我相信任何一天的GCC都会胜过VC.


Joh*_*itb 6

MSVC不实现后期解析方案吗?在这种方案中,编译器不依赖于typename.它只是将所有令牌存储在模板定义的大括号之间,并且在实例化模板时,它会解析这些令牌.既然它知道什么是什么,什么不是什么类型,它将无需工作typename.

但是,如果编译器typename在实例化模板时没有诊断出缺失,那么它就不符合要求.

或者实际上可以推断iterator_category是一个类型还是一个函数,因为它后跟一对括号()?

重要的是名称是否依赖和合格.模板是否可以推断出名称始终是类型并不重要.但是,对于缺失typenames 的错误消息的质量可能很重要.

FWIW,不可能iterator_category在语言层面上推断出任何东西.