自从海湾合作委员会抓住我这个问题已经有一段时间了,但它刚刚发生在今天.但是我从来没有理解为什么GCC在模板中需要typedef typename,而VS和我猜ICC没有.typedef typename是一个"bug"还是一个严格的标准,还是留给编译器编写者的东西?
对于那些不知道我的意思的人来说,这是一个样本:
template<typename KEY, typename VALUE>
bool find(const std::map<KEY,VALUE>& container, const KEY& key)
{
std::map<KEY,VALUE>::const_iterator iter = container.find(key);
return iter!=container.end();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在VS(可能在ICC中)编译,但在GCC中失败,因为它想要这样:
template<typename KEY, typename VALUE>
bool find(const std::map<KEY,VALUE>& container, const KEY& key)
{
typedef typename std::map<KEY,VALUE>::const_iterator iterator; //typedef typename
iterator iter = container.find(key);
return iter!=container.end();
}
Run Code Online (Sandbox Code Playgroud)
注意:这不是我正在使用的实际功能,而只是一些愚蠢的东西来证明这个问题.
在SO上阅读问题,评论和答案,我一直听说MSVC没有正确地实现两阶段模板查找/实例化.
据我所知,到目前为止,MSVC++只对模板类和函数进行了基本的语法检查,并没有检查模板中使用的名称是否至少被声明了或者沿着这些行.
它是否正确?我错过了什么?
在这个问题中,提问者具有以下功能:
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.4和4.5.1下编译,要求a typename
.即便如此,它仍然在Visual Studio 2008和2010下编译得很好.
这只是另一个我不知道的Visual Studio扩展/错误吗?
或者它实际上可以推断出这iterator_category
是一个类型还是一个函数,因为它后跟一对括号()
?(请参阅@ DeadGM 从此处开始的消息.)这可能实际上是GCC中的一个错误吗?