typename的两个意思

effective c++条款42:了解typename的双重意义
记录下自己在看书时认为重要的东西防止忘记…
第一种是应用在template的声明式中:
c++
template
class b1;
template
class b2;

这里的class和typename起的作用是一样的,是等价的,写法的差异来自于没有typename时好多人用class来声明,typename引入后class也没有被废弃,书上说最好是使用typename。

第二种是使用typename标注嵌套从属类型名称,但不可再base class lists(基类列)和member initialization list(成员初值列)内以它作为base class修饰符。
下面介绍从属名称和嵌套从属类型名称。
exm:

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

ps:这些代码是编译不过的,原因是C::const_iterator iter部分会造成歧义,原因是(书中描述):在我们知道C是什么之前,没有任何办法可以知道C::const_iterator 是否为一个类型,而当编译器开始解析template print2nd时,尚未确知c是什么东西,c++有个规则可以解析此一歧义状态:如果解析器在template中遭遇一个嵌套从属名称他便假设这个名称不是个类型,除非你告诉他是,所以缺省情况下嵌套从属名称不是类型,,若要矫正这个形式,我们必须标识c::const_iterator是个类型,代码形式是:

template
void print2nd(const C& container){
    if(container.size()>=2){
        typename C::const_iterator iter(container.begin());
        ...
}

typename必须作为嵌套从属类型名称的前缀词的例外是,不可以出现在base classes list内的嵌套从属类型名称前,也不可在member initialization list 中作为base class修饰符。例如:

templateT>
class derived:public base<T>::nested{ //base class list 中不允许'typename'
public:
    explicit derived(int x):base<T>::nexted(x){//mem.init.list中不允许使用'typename'
        typename base<T>::nested temp;//嵌套从属类型需要加typename
        ...
   }
   ...
};

最后再写一个经常遇见的代码:

templateT>
void workWithIterator<T iter>{
    typename std::iterator_traits<T>::value_type temp(*iter);
    ...
}

作用是:接受一个迭代器,做一份local副本temp。iterator_traints::value_type 的意思是类型为T的对象所指之物的类型。

你可能感兴趣的:(c++effective)