美文网首页
深入理解C++11 2.12 外部模板

深入理解C++11 2.12 外部模板

作者: zinclee123 | 来源:发表于2019-08-08 19:08 被阅读0次

    首先明确什么是“外部”(extern)。比如a.c文件中有个int i,而另一个文件b.c文件中想使用i这个变量,则需要在b.c文件中做一个声明:

    extern int i;
    

    这样的好处是,在分别编译了a.c和b.c之后,其生成的目标文件a.o和b.o中只有i这个符号的一份定义。a.o中的i是实在存在于a.o目标文件的数据区中的数据,而在b.o中,只是记录了i符号会引用其他目标文件中数据区中的名为i的数据。这样一来,在链接器将a.o和b.o链接成单个可执行文件(或者库文件)c的时候,c文件的数据区也只会有一个i的数据。

    而如果b.c中声明int i的时候不加上extern,那么i就会实在存在于a.o和b.o的数据区中,链接器在链接a.o和b.o的时候,就会报错,因为无法决定相同的符号是否需要合并。

    而对于函数模板,比如在test.h的文件中声明如下:
    template<typename T> void fun(T){}
    在test1.cpp中,定义如下

    #include "test.h"
    void test1(){
        fun(3);
    }
    

    在test2.cpp中,定义如下

    #include "test.h"
    void test2(){
        fun(4);
    }
    

    由于两个源代码模板函数参数类型一致,所以实例化出了两个一样的函数fun<int>(int),代码重复,链接器会只保留一份。如果源代码中有过多的模板,编译器会做很多实例化工作,链接器又会做很多去重工作,会导致编译时间和链接时间过长。为了解决这个问题,引入了“外部”模板。

    在C++11中,我们可以使用如下声明,针对上面的代码,我们可以,在test1.cpp中做显示的实例化:

    #include "test.h"
    
    template void fun<int>(int);//显示的实例化
    void test1(){
        fun(3);
    }
    

    在test2.cpp中,做外部模板声明:

    #include "test.h"
    
    extern template void fun<int>(int);//外部模板的声明
    void test2(){
        fun(4);
    }
    

    需要注意,外部模板声明不能用于一个静态函数,但可以用于类静态成员函数。

    相关文章

      网友评论

          本文标题:深入理解C++11 2.12 外部模板

          本文链接:https://www.haomeiwen.com/subject/bqsfjctx.html