zoukankan      html  css  js  c++  java
  • Effective C++ 条款43 学习处理模板化基类内的名称

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

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

    以下代码通不过编译:

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

    因为基类模板(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的内容毫无所悉的缘故.

  • 相关阅读:
    UnixTime的时间戳的转换
    dotnet cors 跨域问题
    sqlServer备份和还原语句
    mvc的生命周期
    Java序列化
    js 分页
    jquery js 分页
    Myeclipse 6.0代码
    前序遍历_中序遍历_后序遍历
    数组去重的一些方法以及数组排序
  • 原文地址:https://www.cnblogs.com/reasno/p/4801220.html
Copyright © 2011-2022 走看看