成员函数模板和模板显式实例化

举报
无敌清风蓝 发表于 2023/08/31 22:04:43 2023/08/31
【摘要】 成员函数模板和模板显式实例化

1.成员函数模板

不论是一个普通的类,还是一个类模板,他成员函数本身可以是一个函数模板,这种成员函数称为“成员函数模板”,但是这种成员函数模板不可以是虚函数,如果是虚函数,则编译器报错

1.普通类的成员函数模板:

class A{
    public:
        template<typename T>
        void myft(T tmpt)
        {
            cout << tmpt << endl;        
        }
}

2.类模板的成员函数模板

template<typename C>
class A
{
public:
    template<typename T2>
    A(T2 v1, T2 v2) //构造函数也引入自己的模板参数T2,和整个类的模板参数C没有关系
    {

    }
    template<typename T>
    void myft(T tmpt)
    {
        cout << tmpt << endl;
    }
    C m_ic;
};

如果想把成员函数模板的实现代码写到类模板定义外面,应该这样写

template<typename C>
class A
{
public:
    template<typename T2>
    A(T2 v1, T2 v2); //构造函数也引入自己的模板参数T2,和整个类的模板参数C没有关系
    template<typename T>
    void myft(T tmpt)
    {
        cout << tmpt << endl;
    }
    C m_ic;
};
template <typename C> // 先跟类模板的模板参数列表,要排在上面(如果排在下面会报错)
template <typename T2> // 再跟构造函数模板自己的模板参数列表
A<C>::A(T2 v1, T2 v2)
{
    cout << v1 << v2 << endl;
}

2.模板显式实例化与声明

前面已经说过模板只有被使用时才会被实例化

就是上面的A类模板,如果放在一个h文件中,有两个cpp同时调用这个h文件,并且都实例化的话,其实是会实例化两个出来的,如果项目很大,有多个cpp,则会实例化很多相同的类模板,开销也很大,增大了编译的时间

可以通过显式实例化来避免这种生成多个相同类模板实例的开销

可以在第一个cpp文件头写上

template A<float> //这叫实例化定义,只有一个cpp文件这样写,编译器为其生成代码
其他cpp的头上声明这个实例化出来的类就行了
extern template A<float> //其他的cpp都这样写

在头上写,是因为编译器遇到这些使用类模板的代码会自动会对模板实例化,所以在cpp头上写的代码肯定比那些使用该类模板的代码先执行到

带extern的代码行,成为模板实例化声明,extern的意思就是告诉编译器,其他的cpp已经有一个类的实例化版本了

template A是类的实例化定义

extern template A是类的实例化声明

只有一个定义,但是可以有多个声明

但是一旦用template A 进行显式实例化的话,系统会把这个类模板以及所有成员函数都给实例化出来(感觉这样并不好),包括内联的成员函数,同时如果代码中调用了哪个函数模板,那么系统也会把这个函数模板根据所调用的参数实例化出来

使用VS17和19的话,不推荐使用类模板显式实例化特色,因为虽然有作用,但是也会把所有成员都实例化出来,增加编译时间和代码长度

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。