打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
typename的两种用法

声明一个类型

typename的第一个作用在于声明一个类型。为什么类型还需要声明呢?因为编译器并不是总会知道哪个名称是个类型。 下面的代码会编译错:

template<typename C>void print2nd(const C& container){    if(container.size() >= 2){        C::const_iterator it(container.begin());        ++it;        int value = *it;          cout<<value;    }}

发生编译错误是因为编译器不知道C::const_iterator是个类型。万一它是个变量呢? C::const_iterator的解析有着逻辑上的矛盾: 直到确定了C是什么东西,编译器才会知道C::const_iterator是不是一个类型; 然而当模板被解析时,C还是不确定的。这时我们声明它为一个类型才能通过编译:

typename C::const_iterator it(container.begin());

嵌套从属名称

事实上类型C::const_iterator依赖于模板参数C, 模板中依赖于模板参数的名称称为从属名称(dependent name), 当一个从属名称嵌套在一个类里面时,称为嵌套从属名称(nested dependent name)。 其实C::const_iterator还是一个嵌套从属类型名称(nested dependent type name)。

嵌套从属名称是需要用typename声明的,其他的名称是不可以用typename声明的。比如下面是一个合法的声明:

template<typename C>void f(const C& container, typename C::iterator iter);

如果你把const C&也声明了typename也是要编译错的哦:

template<typename C>void f(typename const C& container, typename C::iterator iter);

错误输出:

error: expected a qualified name after 'typename'

一个例外

模板中的嵌套从属名称是需要typename声明的,然而有一个例外情况: 在派生子类的基类列表中,以及构造函数的基类初始化列表中,不允许typename声明。 例如Derived<T>继承自Base<T>::Nested

template<typename T>class Derived: public Base<T>::Nested{  // 继承基类列表中不允许声明`typename`public:    explicit Derived(int x): Base<T>::Nested(x){    // 基类初始化列表不允许声明`typename`        typename Base<T>::Nested tmp;   // 这里是要声明的    }};
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
typedef和typename关键字
理解typename的两个含义
C++11 标准新增特性
C 模板详解(一)
C++ 模板基础谈 - C/C++ / C++ 语言
boost::enable_if与SFINAE原则
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服