zoukankan      html  css  js  c++  java
  • C++对象模型——Template中的名称决议方式 (第七章)

    Template中的名称决议方式 (Name Resolution within a Template)

        必须可以区分下面两种意义,一种是C++ Standard所谓的"sope of the template",也就是"定义出template"的程序.还有一种是C++ Standard所谓的"scope of the template instantiation",也就是"具现出template"的程序.
        第一种情况例如以下所看到的:
    // scope of the template definition
    extern double foo(double);
    template <class type>
    class ScopeRules {
    public:
        void invariant() {
            _member = foo(_val);
        }
        type type_dependent() {
            return foo(_member);
        }
        // ...
    private:
        int _val;
        type _member;
    };
        另外一种情况例如以下所看到的:
    // scope of the template instantiation
    extern int foo(int);
    // ...
    ScopeRules<int> sr0;
        在ScopeRules template 中有两个foo()调用操作.在"scope of template definition"中,仅仅有一个foo()函数声明位于scope内.然而在"scope of template instantiation"中,两个foo()函数声明都位于scope内,假设有一个函数调用操作:
    // scope of the template instantiation
    sr0.invariant();
        那么在invariant()中调用的到底是哪一个foo()函数实体呢?


    // 调用的哪一个foo()函数实体
    _member = foo(_val);
        在调用操作的那一点,程序中的两个函数实体是:
    // scope of the template declaration
    extern double foo(double);
    // scope of the template instantiation
    extern int foo(int);
        而_val的类型是 int,那么选中的是哪一个呢?
        结果选中的是直觉以外的那一个:
    // scope of the template declaration 
    extern double foo(double);
        Template中对于一个nonmember name的决议结果是依据这个name的使用是否与"用以具现出该template的參数类型"有关而决定的.假设其使用不相关,那么就以"scope of the template declaration"来决定name.假设其使用互有关联,那么就以"scope of the template instantiation"来决定name.在第一个样例中,foo()与用以具现ScopeRules的參数类型无关:
    // the resolution of foo() is not dependent on the template argument
    _member = foo(_val);
    
        这是由于_val的类型是int;_val是一个"类型不会变动"的 template class member.也就是说,被用来具现出这个 template 的真正类型,对于_val的类型并没有影响.此外,函数的决议结果仅仅和函数的原型有关,和函数的返回值没有关联.因此,_member的类型并不会影响哪一个foo()实体被选中.foo()的调用与 template 參数毫无关联.所以调用操作必须依据"scope of the template declaration"来决议.在此scope中,仅仅有一个foo()候选者.
        以下是与类型相关的使用方法:
    sr0.type_dependent();
        这个函数的内容例如以下:
    return foo(_member);
        它到底会调用哪一个foo()呢?
        这个样例非常清楚与 template 參数有关,由于该參数来决定_member的真正类型.所以这一次foo()必须在"scope of the template instantiation"中决议.
        这意味着一个编译器必须保持两个scope contexts:
        1."scope of the template declaration",用以专注于一般的 template class.
        2."scope of the template instantiation",用以专注于特定的实体.
        编译器的决议算法必须决定哪一个才是适当的scope,然后在当中搜寻适当的name.

    Member Function的具现行为 (Member Function Instantiation)

        对于 template 的支持,最困难的是 template function的具现.眼下的编译器提供两个策略:一个是编译时期策略,程序代码必须在program text file中备妥可用;还有一个是链接时期策略,有一些meta-complication工具能够导引编译器的具现行为.
        以下是编译器设计者必须回答的三个主要问题:
        1.编译器怎样找出函数的定义?


        2.编译器怎样可以仅仅具现出用到的member functions?


        3.编译器怎样阻止member definition在多个.o文件里都被具现呢?


        问题1:方法一是包括 template program text file,就好像它是个header文件一样.方法二是要求一个文件命名规则,比如能够要求在Point.h中发现的函数声明,其 template program text一定要放置于文件Point.c或Point.cpp中.
        问题2:方法1就是忽略这个要求,把一个已经具现出的 class 的全部member functions都产生出来.方法二是仿真链接操作,检測看哪一个函数真正须要,然后仅仅为它产生实体.
        问题3:方法1就是产生多个实体,然后从链接器中提供支持,仅仅留下当中一个实体,其余忽略.方法二是由使用者来导引"仿真链接阶段"的具现策略,决定哪些实体才是所须要的.

  • 相关阅读:
    单片机与嵌入式系统中C语言的位运算小记
    #ifndef、#def、#endif说明
    Freertos学习初识任务函数
    IAR(EWARM)下移植FreeRTOS到STM32F10x笔记
    visio 画 弯曲 箭头 ( 波浪线 曲线)
    dos 中tree的使用方法
    Win7下Borland C++ 4.5 & TASM5.0调试uC/OSII
    (*(volatile unsigned long *)
    有关推挽输出、开漏输出、复用开漏输出、复用推挽输出以及上拉输入、下拉输入、浮空输入、模拟输入区别
    POJ 1236 Network of Schools
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7131182.html
Copyright © 2011-2022 走看看