【C++】typename

 

参考《Effective C++》条款42:Understand the two meaning of typename

1 模板参数列表中与class关键字可相互替换

 

template<typename T>
template<class T>
是一样的

2 嵌套从属名称(nested dependent names)

假如template内出现的名称如果依赖于某个模板参数,则称其为从属名称(dependent names),如果从属名称在class内呈嵌套状则称之为嵌套从属名称(nested dependent names)。
例如:

 

templaet <typename T>
void myPrint(const T& t){
    t::const_iterator iter(t.begin());
}

假设模板参数列表中的参数表示一个容器类型,则我们知道t::const_iterator一个依赖模板参数并且在容器内部,所以t::const_iterator是一个嵌套从属名称。


在我们知道t是什么之前没有办法可以知道t::const_iterator是否是一个类型,因为有还可能是个静态(static)成员变量,考虑下面的例子:

 

template <typename T>
void myPrint(const T& t){
    t::const_iterator * x;
}

如果const_iterator是t的静态成员变量,则上面的t::const_iterator * x;中的*表示乘法,如果是个类型则表示声明一个指向t::const_iterator类型的指针。
从而给编译器造成困惑(因为我们不知道t是什么)。


C++有个规定:当解析器在模板中遇到一个嵌套从属名称时便假定这个名称不是类型,除非你用关键字typename指定它是:

 

template <typename T>
void myPrint(const T& t){
    typename t::const_iterator * x;     //这样便不会造成困惑了
}

同理不仅在内部,在参数列表里也是:

 

template <typename T>
void f(const T& t, typename T::const_iterator cit){     //T不是嵌套从属名称,而T::const_iterator是,所以要在T::const_iterator前面加上typename
        //....
}

3 是嵌套从属名称但不用加typename的两种情况

基类列表(base list)和成员初始化列表(member initializaiton list)

 

template <typename T>
class Derived: public Base<T>::Nested {                 //基类列表中不允许使用typename
public:
    explicit Derived(int x): Base<T>::Nested(int x){    //初始化列表中不允许使用typename
        typename Base<T>::Nested temp;                  //嵌套从属名称(既不在基类列表中又不在初始化列表中)前面必须要加typename
    }
}
 
   

Author: visayafan <visayafan@gmail.com>

Date: 2011-11-29 18:49:57

HTML generated by org-mode 6.33x in emacs 23

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值