关于模板的实例化

2021-09-20  本文已影响0人  404Not_Found

函数模板

template <class T>
T funAdd(const T &a, const T &b)
{
  T value = a+b;
  return value
}

void func()
{
  cout<<funcAdd(1,2)<<endl;
  return;
}

T 的类型,是编译器根据funcAdd 来确定的。

编译器推断类型.PNG
函数体如果不调用函数模板的实例化,即模板函数,则不会出现任何函数模板的字样
但 如果 main不调用,其他功能函数,函数模板还是会进入编译。

类的模板

template<class T>
class ATPL
{
  T m_i, m_j;
  ATPL( T tmpi = 0, tmpj = 0)
  {
    m_i = tmpi;
    m_j = tmpj;
  }
}

void func()
{
}

如果函数没有调用这个 类模板,即没有实例化过,则不会进入编译。

类模板中的枚举

template<class T>
{
  public: 
    enum E
    {
      BUSY;
      FREE;
    }
  public:
    T m_i, m_j;
     ATPL(T tmpi =0, T tmpj = 0)
    {
        m_i = tmpi;
        m_j = tmpj;
    }
}

void func()
{
    ATPL<int>::E myEnum;
    myEnum = ATPL<int>::BUSY;

    ATPL<double>::E myEnum1;
    myEnum1 = ATPL<double>::BUSY;
}

没有什么特别的,编译器只是借用了ATPL<int>::E 中的这个枚举类型,相当于namespace 作用域。
从 obj 文件观察到,只有2个 APTL<int>, APTL<double>, 并没有实例化模板

类模板中的静态变量

    // 类模板中的静态成员
    template<class T>
    class ATPL
    {
    public:
        T m_i, m_j;
        ATPL(T tmpi = 0, T tmpj = 0)
        {
            m_i = tmpi;
            m_j = tmpj;
        }
        static int m_sti;
    };
    // 不适用,模板依然没有实例化
    template <class T> int ATPL<T>::m_sti = 10;

    void func()
    {
        //与作用域无差别, 所以 static 的地址不同,起始就是相当于两个namespace 下的静态
        ATPL<int>::m_sti = 18;
        cout << ATPL<int>::m_sti << endl;

        ATPL<double>::m_sti = 18;
        cout << ATPL<double>::m_sti << endl;

        cout << &ATPL<int>::m_sti << endl;
        cout << &ATPL<double>::m_sti << endl;
    }

理解成 int double ,两个namespace 就好。

类模板的实例化

template <class T>
    class ATPL
    {
    public:
        T m_i, m_j;
        ATPL(T tmpi = 0, T tmpj = 0)
        {
            m_i = tmpi;
            m_j = tmpj;
        }
        static int m_sti;
    };
    void func()
    {
        ATPL<int> * pobj = NULL;//未实例化
        const ATPL<int> & yobj = 0; // 构造函数允许默认参数,也允许隐式类型转换
    }

注意上述代码,一个仅仅是指针,不会发生实例化
另一个是引用 + 允许隐式类型转换,所以是属于实例化。

类模板中的成员函数

    //成员函数实例化
    template <class T>
    class ATPL
    {
    public:
        T m_i, m_j;d
        ATPL(T tmpi = 0, T tmpj = 0)
        {
            m_i = tmpi;
            m_j = tmpj;
        }

        void func1() const
        {
            cout << "func1" << endl;
        }
        void func2() const
        {
            cout << "func2" << endl;
        }
        static int m_sti;
    };
    void func()
    {
        const ATPL<int> & yobj = 0; //没调用成员函数,则没有必进入编译,然而对于虚函数来说,无论是否调用都会进入编译,因为有虚函数就会有虚函数表。
        yobj.func1();//进入编译
    }

模板的编译是非常耗时的。如果其他文件中有定义模板,我想在当前文件中只让某一个成员函数进入编译,或者只想实例化某种类。则如下:

template class ATPL<int>; //如果其他文件中有定义ATPL这个类
template class ATPL<int>::func1()//仅让 func1 进入编译
上一篇 下一篇

猜你喜欢

热点阅读