这在VS2010sp1中没有编译(虽然它用gcc 4.6编译):
template<class T>
struct Upcast;
template<>
struct Upcast<signed char>
{
typedef signed short type;
};
template<>
struct Upcast<char>
{
typedef typename std::conditional<std::is_signed<char>::value,short, unsigned short>::type type;
};
int main()
{
Upcast<char>::type a;
return 0;
}
来自VS的错误:
Error 1 error C2899: typename cannot be used outside a template declaration
哪支球队是对的? VS还是gcc?
答案 0 :(得分:26)
VS在C ++ 03上是正确的。 GCC在C ++ 0x上是正确的。
现在,GCC也可以在C ++ 03模式下允许这种情况(实际编译器在C ++ 03模式下不会诊断出很多事情,实际上只在C ++ 0x中有效),以及VS在C ++ 03模式下拒绝它可能是明智的。
在C ++ 0x中,是否在模板中使用typename QualifiedName
无关紧要。也就是说,以下内容对于C ++ 0x来说是完全合法的:
#include<vector>
int main() {
typename std::vector<int> v;
}
在C ++ 03中,typename
只能在模板中使用。并且代码中的显式特化不是模板。没有template<typename T ...>
子句(代码中的所有参数都是固定的)。
答案 1 :(得分:8)
根据C ++ 03,模板外的任何地方都不允许使用typename
和template
个关键字,包括显式(完整)模板特化。所以根据C ++ 03,MSVC ++是正确的
根据C ++ 0x,此代码是正确的。
答案 2 :(得分:3)
在这种特殊情况下,似乎VS2010拒绝代码是正确的:
14.6 / 5
关键字typename只能应用于限定名称,但这些名称不必相关。关键字typename只能在可以使用从属名称的上下文中使用。这包括模板声明和定义,但排除显式特化声明和显式实例化声明。