C++ template 关键字typename(5.1节, 5.2节)

    本章给出模板的一些更深入的基础知识,它们都是和模板的实际应用密切相关的,包括关键字typename的另一种用法,
把成员函数和嵌套类也定义成模板,模板的模板参数(template template parameters),零初始化和使用字符串作为模板实参时所要注意的一些细节,虽然这些技术具有很强的技巧性,但每个C++程序员日常都应对它略有耳闻。

关键字typename
在C++标准化过程中,引入关键字typename是为了说明:模板内部的标识符可以是一个类型,譬如下面的例子:
template <typename T>
class MyClass {
    typename T::SubType * ptr;
    ...
};
上面程序中,第2个typename被用来说明:SubType是定义于类T内部的一种类型。因此,ptr是一个指向T::SubType类型的指针。
如果不使用typename, SubType就会被认为是一个静态成员,那么它应该是一个具体的变量或对象,于是,下面的表达式:
T::SubType  * ptr
会被看作是类T的静态成员SubType和ptr的乘积。
通常而,当某个依赖于模板参数的名称是一个类型时,就应该使用typename。(这个问题在9.3.2小节详细讨论)
让我们来考虑一个typename的典型应用,即在模板代码中访问STL容器的迭代器:
 

#ifndef PRINTCOLL_H
#define PRINTCOLL_H

#include <iostream>

template <typename T>
void printcoll(T const &coll)
{
    typename T::const_iterator pos;             //用于迭代coll的迭代器
    typename T::const_iterator end(coll.end()); //结束位置
    for(pos = coll.begin(); pos != end; ++pos)
    {
        std::cout << *pos << ' ';
    }
    std::cout << std::endl;
}

#endif // PRINTCOLL_H

 

在这个函数模板中,调用参数是一个T类型的STL容器。为了迭代容器中的所有元素,我们借助于迭代器类型;
而在STL容器类中,有声明迭代器类型const_iterator的都可以使用,比如vector, list,  queue没有这个类型,所有不能使用
下面看具体的示例
 

#include <iostream>
#include "printcoll.h"
#include <vector>
#include <list>
#include <queue>

int main()
{
    std::vector<int> v;
    v.push_back(34);
    v.push_back(23);
    v.push_back(98);
    printcoll(v);

    std::list<int> li;
    li.push_back(56);
    li.push_back(23);
    li.push_back(94);
    printcoll(li);

    std::queue<int> qu;
    qu.push(87);
    qu.push(63);
    qu.push(82);
    //printcoll(qu);//编译错误,const_iterator 未声明的标识符
    std::cout << "Hello World!" << std::endl;
    return 0;
}


.template构造(详细在9.3.3介绍)

 

使用this->
对于具有基类的类模板,自身使用名称x并不一定等同于this->。即使用该x是从基类继承获得的,也是如此。
例如:
template<typename T>
class Base {
    public:
        void exit();
};

template <typename T>
class Derived: Base<T> {
public:
    void foo() {
        exit();//调用外部的exit()或者出现错误
    }
};

在这个例子中,在foo()内部决定要调用哪一个exit()时,并不会考虑基类Base中定义的exit()。因此,你如果不是获取一个错误,就是调用了另一个exit().
这个问题将在9.4.2小节详细讨论。

现在建议你记住一条南规则:对于那些在基类中声明,并且依赖于模板参数的符号(函数或者变量等),你应该在它们前面使用this->或者Base<T>::。如果希望完全避免不确定性,你可以(使用诸如this->和Base<T>::等)限定(模板中)所有的成员访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值