• 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的内容毫无所悉的缘故.

  • 相关阅读:
    zoj 1797 Least Common Multiple
    poj 3233 Matrix Power Series
    使用membership(System.Web.Security)来进行角色与权限管理 (转)
    flashplayer9的全屏模式
    AJAX1.0的UpdateProgress使用
    ASP.NET 2.0中的成员管理与角色管理 (续)
    ASP.net AJAX 调用PageMethods实例
    关于模式窗体的缓存问题的解决方案
    win2003服务器中:无法连接ACCESS数据库/sql数据库正常 && .net程序生成的dll文件拒绝访问问题
    js event 详解
  • 原文地址:https://www.cnblogs.com/reasno/p/4801220.html
Copyright © 2020-2023  润新知