您的位置:首页 > 其它

[转]gcc中使用模板类的类的编译错误

2009-02-27 13:53 260 查看
原文:http://blog.csdn.net/manesking/archive/2008/10/29/3173632.aspx

撰写时间:2008年03月12日
发布时间:2008年10月29日
整理时间:2008年10月29日

最近在自己写的一段代码中,使用了模板类的类,即如下形式:

template<class A>

void func(A)

{

fun2(A::B());

}
即A是一个模板类型,同时使用了A域下的类型B,需要根据A的不同而构造相应的B的实体,进行传递。
此种写法在VC6 + IntelC++9.0环境中能够通过编译,且程序行为与我想要的一致,(后来认为,估计Intel的编译器比较智能,或过于智能)。
但在cygwin + gcc3.4.4中却不能通过编译,其错误信息为:

instantiated from here

error: dependent-name `A::B' is parsed as a non-type, but instantiation yields a type

note: say `typename A::B' if a type is meant

其大致意思为:“编译器解析A::B不是个类型,但却要被初始化为一个类型。”

但是A::B确实是一个类型,这是基于我们通常使用类或名字空间下的子类的惯用语法,考虑可能是gcc对模板类的这种情况考虑不周,因而没能解析出这种用法。

随后又将该错误信息在百度里搜了一下,结果得到了正确的答案:

原来标准c++要求显示地声明一个类型是模板类型,诸如此类的如list<T>::iterater(当T是模板类型时),
包括vector,map都会有这样的问题,理由是具体类型的空间域名也是个“不确定”类型,所以要求有显示地typename声明,指示它是个模板类型
或名字。

其实gcc足够“聪明”,在错误信息里它已经提示你(最后一句话):“使用typename关键字声明,如果它是一个类型的含义”。只是我当时没有仔细看懂,呵呵。

如此修改即可:

template<class A>

void func(A)

{

fun2(typename A::B()); //在前面加typename即可,这里不接受”class”

}

此外,从这一点上,可以看到typename关键字在模板编程中有其独特的用法,而并不是与最初的理解那样,是个可以与class混用,可有可无的东西,建议将template<class A>语法中的class都替换为typename,可能会更规范些。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐