在这个问题中,提问者有以下功能:
template<typename ITER>
bool nextPermutation(ITER start, ITER end)
{
return nextPermutation(start, end, std::iterator_traits<ITER>::iterator_category());
}
为什么在std::iterator_traits
之前不需要typename
?我认为它是需要嵌套类型的模板,如果模板是依赖于模板参数本身?GCC似乎支持我的想法,因为它不能在4.3.4和4.5.1下编译,需要typename
。即便如此,它在Visual Studio 2008和2010下仍然可以很好地编译。
这只是另一个我不知道的Visual Studio扩展/bug吗?
或者实际上有可能推断出iterator_category
是一个类型或一个函数,因为它后面跟着一对括号()
?(看@DeadGM的消息从这里开始。)这可能是GCC中的一个bug吗?
众所周知,Visual c++不(完全)支持两阶段查找,这是首先需要typename
的根本原因。如果编译器不完全支持这一点,它可能在实例化模板之前无法完全解析模板,此时它"知道"std::iterator_traits<ITER>::iterator_category
是一个类型。显然,这种缺陷也延伸到VC10。
说到typename
,我更相信GCC而不是VC。
MSVC不实现后解析方案吗?在这种方案中,编译器不依赖于typename
。它只是将所有标记存储在模板定义的大括号之间,当模板实例化时,它解析这些标记。因为它知道什么是类型,什么不是类型,所以没有typename
也可以工作。
但是,如果编译器在实例化模板时没有诊断缺失的typename
,那么它是不符合的。
或者实际上有可能推断出iterator_category是类型还是函数,因为它后面跟着一对括号()?
重要的是名称是否依赖和限定。模板本身是否能够推断出名称总是一个类型并不重要。但是,缺少typename
s可能会影响错误消息的质量。
顺便说一句,不,在语言层面上推断iterator_category
是不可能的。