Effective C++ 条款43 学习处理模板化基类内的名称

1. 在继承模板基类时,C++拒绝在模板化基类(templatized base classes)内寻找继承而来的名称,例如,对于以下模板基类:

template<typename T>
class Base{
public:
    void fun(){
        ...
    }
    ...
private:
    ...
}

以下代码通不过编译:

template<typename T>
class Derived:public Base<T>{
public:
    void useFun(){
        fun();  //通不过编译,因为编译器拒绝在Base类模板中查找fun
    }
    ...
private:
    ...
}

因为基类模板(base classe templates)有可能被特化,而那个特化版本可能不提供和一般性template相同的接口,因而C++拒绝在模板化基类中查找继承而来的名称.

2. 解决方法有三:

    1). 在base class函数调用动作之前加上this->,即将对fun的调用改为如下:

this->fun();

2). 使用using 声明式,使编译器在模板作用域中查找改名字,即在Derived中加入:

using Base<T>::fun;

这里using声明式的作用和条款33不同,它解决的并不是基类名字被派生类掩盖的问题,而是编译器不进入base class作用域内查找的问题

    3). 明确指出被调用的函数位于base class内,即将对fun的调用改为如下:

Base<T>::fun();

这种方式的缺点在于,如果被调用的函数是虚函数,上述的"明确资格修饰"(explict qualification)会关闭"virtual绑定行为".

3. 从名称可视点的角度出发,2中的每一个解法所做事情都相同:对编译器承诺"base classes template的任何特化版本都将支持其一般化版本所提供的接口".这个承诺是编译器在解析像Derived这样的派生类模板(derived class template)所需要的.但如果这个承诺未被实现即特化的Base不支持派生类模板Derived所要求的接口,最终还是不能通过编译.C++的策略是较早诊断,因此它假设它对那些base classes的内容毫无所悉的缘故.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值