位置: IT常识 - 正文
推荐整理分享<一>函数模板(函数模拟图),希望有所帮助,仅作参考,欢迎阅读内容。
文章相关热门搜索词:函数模型大全,一个函数的模怎么算,函数求模公式,函数模型公式,函数模型及其应用视频讲解,函数模型大全,函数模型大全,函数的模,内容如对您有帮助,希望把文章链接给更多的朋友!
函数模板模板的意义:对类型也参数化int sum1(int a,int b){return a+b;}double sum2(double a ,double b){return a+b;}
几个概念函数模板模板的实例化模板函数
模板类型参数模板非类型参数
模板实参推演模板的特例化模板函数,模板的特例化,非模板函数的重载关系
点击查看代码template<typename T,typename E> //定义一个模板参数列表 或者用 class T 也可以bool compare(T x ){ //compare 是一个函数模板,它目前只是个模板 cout<<"Template Compare"<<endl; return x>y;}int main(){ //函数的调用点,在函数调用点,编译器用用户指定的类型,从原模板实例化一份函数代码出来 // bool compare<int>(int a,int b){return a>b;} 这个从模板实例化出来的函数 就叫模板函数 // bool compare<double>(double a, double b){return a>b} 这个从模板实例化出来的函数 就叫模板函数 //模板函数是编译器根据指定的类型从模板实例化出来 参与编译的函数 //从用户的角度来看,我们只写了一份模板代码,代码量是变少了,但是对于编译器来说,需要编译的代码没有减少,都需要根据指定的类型实例化出来具体函数 compare<int>(1,2);// compare(100,200);//也可以,编译器会根据实参类型进行推演出 compare<int> 进行模板的实例化. //注意如果有compare<int>(1,2); 然后有compare(100,200); //编译器不会生成两套同样的 bool compare<int>(int a,int b){return a>b;},因为这个函数是需要在编译期间生成符号表, //如果生成两次,会出现在符号表中重名问题 return 1;}示例代码2 不实例话模板 并查看编译后.o文件中的 符号表情况
点击查看代码#include <iostream>using namespace std;template<typename T>bool compare(T x,T y){ return x,y;}int main(){ return 1;}//编译后查看.o文件中的符号表信息如下 符号表中看不到compare函数的符号kl@kl-ThinkPad-T580:/data/usershare/code/compile$ objdump -t test1.otest1.o: 文件格式 elf64-x86-64SYMBOL TABLE:0000000000000318 l d .interp 0000000000000000 .interp0000000000000338 l d .note.gnu.property 0000000000000000 .note.gnu.property0000000000000358 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id000000000000037c l d .note.ABI-tag 0000000000000000 .note.ABI-tag00000000000003a0 l d .gnu.hash 0000000000000000 .gnu.hash00000000000003c8 l d .dynsym 0000000000000000 .dynsym00000000000004a0 l d .dynstr 0000000000000000 .dynstr0000000000000576 l d .gnu.version 0000000000000000 .gnu.version0000000000000588 l d .gnu.version_r 0000000000000000 .gnu.version_r00000000000005c8 l d .rela.dyn 0000000000000000 .rela.dyn00000000000006b8 l d .rela.plt 0000000000000000 .rela.plt0000000000001000 l d .init 0000000000000000 .init0000000000001020 l d .plt 0000000000000000 .plt0000000000001050 l d .plt.got 0000000000000000 .plt.got0000000000001060 l d .plt.sec 0000000000000000 .plt.sec0000000000001080 l d .text 0000000000000000 .text0000000000001258 l d .fini 0000000000000000 .fini0000000000002000 l d .rodata 0000000000000000 .rodata0000000000002008 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr0000000000002060 l d .eh_frame 0000000000000000 .eh_frame0000000000003d90 l d .init_array 0000000000000000 .init_array0000000000003da0 l d .fini_array 0000000000000000 .fini_array0000000000003da8 l d .dynamic 0000000000000000 .dynamic0000000000003fa8 l d .got 0000000000000000 .got0000000000004000 l d .data 0000000000000000 .data0000000000004010 l d .bss 0000000000000000 .bss0000000000000000 l d .comment 0000000000000000 .comment0000000000000000 l df *ABS* 0000000000000000 crtstuff.c00000000000010b0 l F .text 0000000000000000 deregister_tm_clones00000000000010e0 l F .text 0000000000000000 register_tm_clones0000000000001120 l F .text 0000000000000000 __do_global_dtors_aux0000000000004010 l O .bss 0000000000000001 completed.80590000000000003da0 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry0000000000001160 l F .text 0000000000000000 frame_dummy0000000000003d90 l O .init_array 0000000000000000 __frame_dummy_init_array_entry0000000000000000 l df *ABS* 0000000000000000 TemplateTest1.cpp0000000000002004 l O .rodata 0000000000000001 _ZStL19piecewise_construct0000000000004011 l O .bss 0000000000000001 _ZStL8__ioinit0000000000001178 l F .text 000000000000004d _Z41__static_initialization_and_destruction_0ii00000000000011c5 l F .text 0000000000000019 _GLOBAL__sub_I_main0000000000000000 l df *ABS* 0000000000000000 crtstuff.c00000000000021a4 l O .eh_frame 0000000000000000 __FRAME_END__0000000000000000 l df *ABS* 0000000000000000 0000000000002008 l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR0000000000001000 l F .init 0000000000000000 _init0000000000003da8 l O .dynamic 0000000000000000 _DYNAMIC0000000000003da0 l .init_array 0000000000000000 __init_array_end0000000000003d90 l .init_array 0000000000000000 __init_array_start0000000000003fa8 l O .got 0000000000000000 _GLOBAL_OFFSET_TABLE_0000000000004010 g .data 0000000000000000 _edata0000000000004000 w .data 0000000000000000 data_start0000000000002000 g O .rodata 0000000000000004 _IO_stdin_used0000000000000000 w F *UND* 0000000000000000 __cxa_finalize@@GLIBC_2.2.50000000000001169 g F .text 000000000000000f main0000000000004008 g O .data 0000000000000000 .hidden __dso_handle0000000000001258 g F .fini 0000000000000000 .hidden _fini0000000000000000 F *UND* 0000000000000000 __cxa_atexit@@GLIBC_2.2.50000000000001080 g F .text 000000000000002f _start0000000000004010 g O .data 0000000000000000 .hidden __TMC_END__0000000000004000 g .data 0000000000000000 __data_start0000000000004018 g .bss 0000000000000000 _end0000000000004010 g .bss 0000000000000000 __bss_start0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.400000000000011e0 g F .text 0000000000000065 __libc_csu_init0000000000000000 w *UND* 0000000000000000 _ITM_deregisterTMCloneTable0000000000001250 g F .text 0000000000000005 __libc_csu_fini0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.50000000000000000 w *UND* 0000000000000000 __gmon_start__0000000000000000 w *UND* 0000000000000000 _ITM_registerTMCloneTable0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4示例代码3 实例化模板 并查看编译后.o文件中的 符号表情况
点击查看代码#include <iostream>using namespace std;template<typename T>bool compare(T x,T y){ return x,y;}int main(){ bool b=compare<int>(100,200); return 1;}//编译生成.o文件,查看其中的符号表信息, 在其中找到了 compare函数的符号表kl@kl-ThinkPad-T580:/data/usershare/code/compile$ objdump -t test1.otest1.o: 文件格式 elf64-x86-64SYMBOL TABLE:0000000000000318 l d .interp 0000000000000000 .interp0000000000000338 l d .note.gnu.property 0000000000000000 .note.gnu.property0000000000000358 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id000000000000037c l d .note.ABI-tag 0000000000000000 .note.ABI-tag00000000000003a0 l d .gnu.hash 0000000000000000 .gnu.hash00000000000003c8 l d .dynsym 0000000000000000 .dynsym00000000000004a0 l d .dynstr 0000000000000000 .dynstr0000000000000576 l d .gnu.version 0000000000000000 .gnu.version0000000000000588 l d .gnu.version_r 0000000000000000 .gnu.version_r00000000000005c8 l d .rela.dyn 0000000000000000 .rela.dyn00000000000006b8 l d .rela.plt 0000000000000000 .rela.plt0000000000001000 l d .init 0000000000000000 .init0000000000001020 l d .plt 0000000000000000 .plt0000000000001050 l d .plt.got 0000000000000000 .plt.got0000000000001060 l d .plt.sec 0000000000000000 .plt.sec0000000000001080 l d .text 0000000000000000 .text0000000000001288 l d .fini 0000000000000000 .fini0000000000002000 l d .rodata 0000000000000000 .rodata0000000000002008 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr0000000000002068 l d .eh_frame 0000000000000000 .eh_frame0000000000003d90 l d .init_array 0000000000000000 .init_array0000000000003da0 l d .fini_array 0000000000000000 .fini_array0000000000003da8 l d .dynamic 0000000000000000 .dynamic0000000000003fa8 l d .got 0000000000000000 .got0000000000004000 l d .data 0000000000000000 .data0000000000004010 l d .bss 0000000000000000 .bss0000000000000000 l d .comment 0000000000000000 .comment0000000000000000 l df *ABS* 0000000000000000 crtstuff.c00000000000010b0 l F .text 0000000000000000 deregister_tm_clones00000000000010e0 l F .text 0000000000000000 register_tm_clones0000000000001120 l F .text 0000000000000000 __do_global_dtors_aux0000000000004010 l O .bss 0000000000000001 completed.80590000000000003da0 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry0000000000001160 l F .text 0000000000000000 frame_dummy0000000000003d90 l O .init_array 0000000000000000 __frame_dummy_init_array_entry0000000000000000 l df *ABS* 0000000000000000 TemplateTest1.cpp0000000000002004 l O .rodata 0000000000000001 _ZStL19piecewise_construct0000000000004011 l O .bss 0000000000000001 _ZStL8__ioinit000000000000118e l F .text 000000000000004d _Z41__static_initialization_and_destruction_0ii00000000000011db l F .text 0000000000000019 _GLOBAL__sub_I_main0000000000000000 l df *ABS* 0000000000000000 crtstuff.c00000000000021cc l O .eh_frame 0000000000000000 __FRAME_END__0000000000000000 l df *ABS* 0000000000000000 0000000000002008 l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR0000000000001000 l F .init 0000000000000000 _init0000000000003da8 l O .dynamic 0000000000000000 _DYNAMIC0000000000003da0 l .init_array 0000000000000000 __init_array_end0000000000003d90 l .init_array 0000000000000000 __init_array_start0000000000003fa8 l O .got 0000000000000000 _GLOBAL_OFFSET_TABLE_0000000000004010 g .data 0000000000000000 _edata00000000000011f4 w F .text 0000000000000017 _Z7compareIiEbT_S0_ //compare函数的符号0000000000004000 w .data 0000000000000000 data_start0000000000002000 g O .rodata 0000000000000004 _IO_stdin_used0000000000000000 w F *UND* 0000000000000000 __cxa_finalize@@GLIBC_2.2.50000000000001169 g F .text 0000000000000025 main0000000000004008 g O .data 0000000000000000 .hidden __dso_handle0000000000001288 g F .fini 0000000000000000 .hidden _fini0000000000000000 F *UND* 0000000000000000 __cxa_atexit@@GLIBC_2.2.50000000000001080 g F .text 000000000000002f _start0000000000004010 g O .data 0000000000000000 .hidden __TMC_END__0000000000004000 g .data 0000000000000000 __data_start0000000000004018 g .bss 0000000000000000 _end0000000000004010 g .bss 0000000000000000 __bss_start0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.40000000000001210 g F .text 0000000000000065 __libc_csu_init0000000000000000 w *UND* 0000000000000000 _ITM_deregisterTMCloneTable0000000000001280 g F .text 0000000000000005 __libc_csu_fini0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.50000000000000000 w *UND* 0000000000000000 __gmon_start__0000000000000000 w *UND* 0000000000000000 _ITM_registerTMCloneTable0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4示例代码4 实例化2次模板一次指定类型,一次参数类型自动推演 两个类型是一样的情况下 并查看编译后.o文件中的 符号表情况
点击查看代码#include <iostream>using namespace std;template<typename T>bool compare(T x,T y){ return x,y;}int main(){ bool b =compare<int>(100,200); bool b2=compare(400,200); return 1;}//编译生成.o文件,查看其中的符号表信息, 在其中找到了一处compare函数的符号表kl@kl-ThinkPad-T580:/data/usershare/code/compile$ objdump -t test1.otest1.o: 文件格式 elf64-x86-64SYMBOL TABLE:0000000000000318 l d .interp 0000000000000000 .interp0000000000000338 l d .note.gnu.property 0000000000000000 .note.gnu.property0000000000000358 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id000000000000037c l d .note.ABI-tag 0000000000000000 .note.ABI-tag00000000000003a0 l d .gnu.hash 0000000000000000 .gnu.hash00000000000003c8 l d .dynsym 0000000000000000 .dynsym00000000000004a0 l d .dynstr 0000000000000000 .dynstr0000000000000576 l d .gnu.version 0000000000000000 .gnu.version0000000000000588 l d .gnu.version_r 0000000000000000 .gnu.version_r00000000000005c8 l d .rela.dyn 0000000000000000 .rela.dyn00000000000006b8 l d .rela.plt 0000000000000000 .rela.plt0000000000001000 l d .init 0000000000000000 .init0000000000001020 l d .plt 0000000000000000 .plt0000000000001050 l d .plt.got 0000000000000000 .plt.got0000000000001060 l d .plt.sec 0000000000000000 .plt.sec0000000000001080 l d .text 0000000000000000 .text0000000000001298 l d .fini 0000000000000000 .fini0000000000002000 l d .rodata 0000000000000000 .rodata0000000000002008 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr0000000000002068 l d .eh_frame 0000000000000000 .eh_frame0000000000003d90 l d .init_array 0000000000000000 .init_array0000000000003da0 l d .fini_array 0000000000000000 .fini_array0000000000003da8 l d .dynamic 0000000000000000 .dynamic0000000000003fa8 l d .got 0000000000000000 .got0000000000004000 l d .data 0000000000000000 .data0000000000004010 l d .bss 0000000000000000 .bss0000000000000000 l d .comment 0000000000000000 .comment0000000000000000 l df *ABS* 0000000000000000 crtstuff.c00000000000010b0 l F .text 0000000000000000 deregister_tm_clones00000000000010e0 l F .text 0000000000000000 register_tm_clones0000000000001120 l F .text 0000000000000000 __do_global_dtors_aux0000000000004010 l O .bss 0000000000000001 completed.80590000000000003da0 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry0000000000001160 l F .text 0000000000000000 frame_dummy0000000000003d90 l O .init_array 0000000000000000 __frame_dummy_init_array_entry0000000000000000 l df *ABS* 0000000000000000 TemplateTest1.cpp0000000000002004 l O .rodata 0000000000000001 _ZStL19piecewise_construct0000000000004011 l O .bss 0000000000000001 _ZStL8__ioinit00000000000011a0 l F .text 000000000000004d _Z41__static_initialization_and_destruction_0ii00000000000011ed l F .text 0000000000000019 _GLOBAL__sub_I_main0000000000000000 l df *ABS* 0000000000000000 crtstuff.c00000000000021cc l O .eh_frame 0000000000000000 __FRAME_END__0000000000000000 l df *ABS* 0000000000000000 0000000000002008 l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR0000000000001000 l F .init 0000000000000000 _init0000000000003da8 l O .dynamic 0000000000000000 _DYNAMIC0000000000003da0 l .init_array 0000000000000000 __init_array_end0000000000003d90 l .init_array 0000000000000000 __init_array_start0000000000003fa8 l O .got 0000000000000000 _GLOBAL_OFFSET_TABLE_0000000000004010 g .data 0000000000000000 _edata0000000000001206 w F .text 0000000000000017 _Z7compareIiEbT_S0_ //此处为compare的函数符号0000000000004000 w .data 0000000000000000 data_start0000000000002000 g O .rodata 0000000000000004 _IO_stdin_used0000000000000000 w F *UND* 0000000000000000 __cxa_finalize@@GLIBC_2.2.50000000000001169 g F .text 0000000000000037 main0000000000004008 g O .data 0000000000000000 .hidden __dso_handle0000000000001298 g F .fini 0000000000000000 .hidden _fini0000000000000000 F *UND* 0000000000000000 __cxa_atexit@@GLIBC_2.2.50000000000001080 g F .text 000000000000002f _start0000000000004010 g O .data 0000000000000000 .hidden __TMC_END__0000000000004000 g .data 0000000000000000 __data_start0000000000004018 g .bss 0000000000000000 _end0000000000004010 g .bss 0000000000000000 __bss_start0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.40000000000001220 g F .text 0000000000000065 __libc_csu_init0000000000000000 w *UND* 0000000000000000 _ITM_deregisterTMCloneTable0000000000001290 g F .text 0000000000000005 __libc_csu_fini0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.50000000000000000 w *UND* 0000000000000000 __gmon_start__0000000000000000 w *UND* 0000000000000000 _ITM_registerTMCloneTable0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4示例代码5 实例化2次模板 两次模板的参数类型不一样 并查看编译后.o文件中的 符号表情况
点击查看代码#include <iostream>using namespace std;template<typename T>bool compare(T x,T y){ return x,y;}int main(){ bool b =compare<int>(100,200); bool b2=compare(400,200); bool b3=compare<double>(1.0,2.0); return 1;}//编译生成.o文件,查看其中的符号表信息, 在其中找到了两处处compare函数的符号表,一次是int 一次是doublekl@kl-ThinkPad-T580:/data/usershare/code/compile$ g++ TemplateTest1.cpp -o test1.okl@kl-ThinkPad-T580:/data/usershare/code/compile$ objdump -t test1.otest1.o: 文件格式 elf64-x86-64SYMBOL TABLE:0000000000000318 l d .interp 0000000000000000 .interp0000000000000338 l d .note.gnu.property 0000000000000000 .note.gnu.property0000000000000358 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id000000000000037c l d .note.ABI-tag 0000000000000000 .note.ABI-tag00000000000003a0 l d .gnu.hash 0000000000000000 .gnu.hash00000000000003c8 l d .dynsym 0000000000000000 .dynsym00000000000004a0 l d .dynstr 0000000000000000 .dynstr0000000000000576 l d .gnu.version 0000000000000000 .gnu.version0000000000000588 l d .gnu.version_r 0000000000000000 .gnu.version_r00000000000005c8 l d .rela.dyn 0000000000000000 .rela.dyn00000000000006b8 l d .rela.plt 0000000000000000 .rela.plt0000000000001000 l d .init 0000000000000000 .init0000000000001020 l d .plt 0000000000000000 .plt0000000000001050 l d .plt.got 0000000000000000 .plt.got0000000000001060 l d .plt.sec 0000000000000000 .plt.sec0000000000001080 l d .text 0000000000000000 .text00000000000012e8 l d .fini 0000000000000000 .fini0000000000002000 l d .rodata 0000000000000000 .rodata0000000000002020 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr0000000000002088 l d .eh_frame 0000000000000000 .eh_frame0000000000003d90 l d .init_array 0000000000000000 .init_array0000000000003da0 l d .fini_array 0000000000000000 .fini_array0000000000003da8 l d .dynamic 0000000000000000 .dynamic0000000000003fa8 l d .got 0000000000000000 .got0000000000004000 l d .data 0000000000000000 .data0000000000004010 l d .bss 0000000000000000 .bss0000000000000000 l d .comment 0000000000000000 .comment0000000000000000 l df *ABS* 0000000000000000 crtstuff.c00000000000010b0 l F .text 0000000000000000 deregister_tm_clones00000000000010e0 l F .text 0000000000000000 register_tm_clones0000000000001120 l F .text 0000000000000000 __do_global_dtors_aux0000000000004010 l O .bss 0000000000000001 completed.80590000000000003da0 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry0000000000001160 l F .text 0000000000000000 frame_dummy0000000000003d90 l O .init_array 0000000000000000 __frame_dummy_init_array_entry0000000000000000 l df *ABS* 0000000000000000 TemplateTest1.cpp0000000000002008 l O .rodata 0000000000000001 _ZStL19piecewise_construct0000000000004011 l O .bss 0000000000000001 _ZStL8__ioinit00000000000011c0 l F .text 000000000000004d _Z41__static_initialization_and_destruction_0ii000000000000120d l F .text 0000000000000019 _GLOBAL__sub_I_main0000000000000000 l df *ABS* 0000000000000000 crtstuff.c000000000000220c l O .eh_frame 0000000000000000 __FRAME_END__0000000000000000 l df *ABS* 0000000000000000 0000000000002020 l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR0000000000001000 l F .init 0000000000000000 _init0000000000003da8 l O .dynamic 0000000000000000 _DYNAMIC0000000000003da0 l .init_array 0000000000000000 __init_array_end0000000000003d90 l .init_array 0000000000000000 __init_array_start0000000000003fa8 l O .got 0000000000000000 _GLOBAL_OFFSET_TABLE_0000000000004010 g .data 0000000000000000 _edata0000000000001226 w F .text 0000000000000017 _Z7compareIiEbT_S0_ //compare<int>(int a,int b) 函数符号0000000000004000 w .data 0000000000000000 data_start0000000000002000 g O .rodata 0000000000000004 _IO_stdin_used0000000000000000 w F *UND* 0000000000000000 __cxa_finalize@@GLIBC_2.2.50000000000001169 g F .text 0000000000000057 main0000000000004008 g O .data 0000000000000000 .hidden __dso_handle00000000000012e8 g F .fini 0000000000000000 .hidden _fini000000000000123d w F .text 0000000000000031 _Z7compareIdEbT_S0_ //compare<double>(double a ,double b) 函数符号0000000000000000 F *UND* 0000000000000000 __cxa_atexit@@GLIBC_2.2.50000000000001080 g F .text 000000000000002f _start0000000000004010 g O .data 0000000000000000 .hidden __TMC_END__0000000000004000 g .data 0000000000000000 __data_start0000000000004018 g .bss 0000000000000000 _end0000000000004010 g .bss 0000000000000000 __bss_start0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.40000000000001270 g F .text 0000000000000065 __libc_csu_init0000000000000000 w *UND* 0000000000000000 _ITM_deregisterTMCloneTable00000000000012e0 g F .text 0000000000000005 __libc_csu_fini0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.50000000000000000 w *UND* 0000000000000000 __gmon_start__0000000000000000 w *UND* 0000000000000000 _ITM_registerTMCloneTable0000000000000000 F *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4//我们顺便看一下.o 文件生成的指令 kl@kl-ThinkPad-T580:/data/usershare/code/compile$ objdump -S test1.otest1.o: 文件格式 elf64-x86-64Disassembly of section .init:0000000000001000 <_init>: 1000: f3 0f 1e fa endbr64 1004: 48 83 ec 08 sub $0x8,%rsp 1008: 48 8b 05 d9 2f 00 00 mov 0x2fd9(%rip),%rax # 3fe8 <__gmon_start__> 100f: 48 85 c0 test %rax,%rax 1012: 74 02 je 1016 <_init+0x16> 1014: ff d0 callq *%rax 1016: 48 83 c4 08 add $0x8,%rsp 101a: c3 retq Disassembly of section .plt:0000000000001020 <.plt>: 1020: ff 35 8a 2f 00 00 pushq 0x2f8a(%rip) # 3fb0 <_GLOBAL_OFFSET_TABLE_+0x8> 1026: f2 ff 25 8b 2f 00 00 bnd jmpq *0x2f8b(%rip) # 3fb8 <_GLOBAL_OFFSET_TABLE_+0x10> 102d: 0f 1f 00 nopl (%rax) 1030: f3 0f 1e fa endbr64 1034: 68 00 00 00 00 pushq $0x0 1039: f2 e9 e1 ff ff ff bnd jmpq 1020 <.plt> 103f: 90 nop 1040: f3 0f 1e fa endbr64 1044: 68 01 00 00 00 pushq $0x1 1049: f2 e9 d1 ff ff ff bnd jmpq 1020 <.plt> 104f: 90 nopDisassembly of section .plt.got:0000000000001050 <__cxa_finalize@plt>: 1050: f3 0f 1e fa endbr64 1054: f2 ff 25 75 2f 00 00 bnd jmpq *0x2f75(%rip) # 3fd0 <__cxa_finalize@GLIBC_2.2.5> 105b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)Disassembly of section .plt.sec:0000000000001060 <__cxa_atexit@plt>: 1060: f3 0f 1e fa endbr64 1064: f2 ff 25 55 2f 00 00 bnd jmpq *0x2f55(%rip) # 3fc0 <__cxa_atexit@GLIBC_2.2.5> 106b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)0000000000001070 <_ZNSt8ios_base4InitC1Ev@plt>: 1070: f3 0f 1e fa endbr64 1074: f2 ff 25 4d 2f 00 00 bnd jmpq *0x2f4d(%rip) # 3fc8 <_ZNSt8ios_base4InitC1Ev@GLIBCXX_3.4> 107b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)Disassembly of section .text:0000000000001080 <_start>: 1080: f3 0f 1e fa endbr64 1084: 31 ed xor %ebp,%ebp 1086: 49 89 d1 mov %rdx,%r9 1089: 5e pop %rsi 108a: 48 89 e2 mov %rsp,%rdx 108d: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 1091: 50 push %rax 1092: 54 push %rsp 1093: 4c 8d 05 46 02 00 00 lea 0x246(%rip),%r8 # 12e0 <__libc_csu_fini> 109a: 48 8d 0d cf 01 00 00 lea 0x1cf(%rip),%rcx # 1270 <__libc_csu_init> 10a1: 48 8d 3d c1 00 00 00 lea 0xc1(%rip),%rdi # 1169 <main> 10a8: ff 15 32 2f 00 00 callq *0x2f32(%rip) # 3fe0 <__libc_start_main@GLIBC_2.2.5> 10ae: f4 hlt 10af: 90 nop00000000000010b0 <deregister_tm_clones>: 10b0: 48 8d 3d 59 2f 00 00 lea 0x2f59(%rip),%rdi # 4010 <__TMC_END__> 10b7: 48 8d 05 52 2f 00 00 lea 0x2f52(%rip),%rax # 4010 <__TMC_END__> 10be: 48 39 f8 cmp %rdi,%rax 10c1: 74 15 je 10d8 <deregister_tm_clones+0x28> 10c3: 48 8b 05 0e 2f 00 00 mov 0x2f0e(%rip),%rax # 3fd8 <_ITM_deregisterTMCloneTable> 10ca: 48 85 c0 test %rax,%rax 10cd: 74 09 je 10d8 <deregister_tm_clones+0x28> 10cf: ff e0 jmpq *%rax 10d1: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 10d8: c3 retq 10d9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)00000000000010e0 <register_tm_clones>: 10e0: 48 8d 3d 29 2f 00 00 lea 0x2f29(%rip),%rdi # 4010 <__TMC_END__> 10e7: 48 8d 35 22 2f 00 00 lea 0x2f22(%rip),%rsi # 4010 <__TMC_END__> 10ee: 48 29 fe sub %rdi,%rsi 10f1: 48 89 f0 mov %rsi,%rax 10f4: 48 c1 ee 3f shr $0x3f,%rsi 10f8: 48 c1 f8 03 sar $0x3,%rax 10fc: 48 01 c6 add %rax,%rsi 10ff: 48 d1 fe sar %rsi 1102: 74 14 je 1118 <register_tm_clones+0x38> 1104: 48 8b 05 e5 2e 00 00 mov 0x2ee5(%rip),%rax # 3ff0 <_ITM_registerTMCloneTable> 110b: 48 85 c0 test %rax,%rax 110e: 74 08 je 1118 <register_tm_clones+0x38> 1110: ff e0 jmpq *%rax 1112: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 1118: c3 retq 1119: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)0000000000001120 <__do_global_dtors_aux>: 1120: f3 0f 1e fa endbr64 1124: 80 3d e5 2e 00 00 00 cmpb $0x0,0x2ee5(%rip) # 4010 <__TMC_END__> 112b: 75 2b jne 1158 <__do_global_dtors_aux+0x38> 112d: 55 push %rbp 112e: 48 83 3d 9a 2e 00 00 cmpq $0x0,0x2e9a(%rip) # 3fd0 <__cxa_finalize@GLIBC_2.2.5> 1135: 00 1136: 48 89 e5 mov %rsp,%rbp 1139: 74 0c je 1147 <__do_global_dtors_aux+0x27> 113b: 48 8b 3d c6 2e 00 00 mov 0x2ec6(%rip),%rdi # 4008 <__dso_handle> 1142: e8 09 ff ff ff callq 1050 <__cxa_finalize@plt> 1147: e8 64 ff ff ff callq 10b0 <deregister_tm_clones> 114c: c6 05 bd 2e 00 00 01 movb $0x1,0x2ebd(%rip) # 4010 <__TMC_END__> 1153: 5d pop %rbp 1154: c3 retq 1155: 0f 1f 00 nopl (%rax) 1158: c3 retq 1159: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)0000000000001160 <frame_dummy>: 1160: f3 0f 1e fa endbr64 1164: e9 77 ff ff ff jmpq 10e0 <register_tm_clones>0000000000001169 <main>: 1169: f3 0f 1e fa endbr64 116d: 55 push %rbp 116e: 48 89 e5 mov %rsp,%rbp 1171: 48 83 ec 10 sub $0x10,%rsp 1175: be c8 00 00 00 mov $0xc8,%esi 117a: bf 64 00 00 00 mov $0x64,%edi 117f: e8 a2 00 00 00 callq 1226 <_Z7compareIiEbT_S0_> //compare<int>(100,200); 1184: 88 45 fd mov %al,-0x3(%rbp) 1187: be c8 00 00 00 mov $0xc8,%esi 118c: bf 90 01 00 00 mov $0x190,%edi 1191: e8 90 00 00 00 callq 1226 <_Z7compareIiEbT_S0_> //compare(400,200); 和上面调用的函数是一个函数 1196: 88 45 fe mov %al,-0x2(%rbp) 1199: f2 0f 10 05 6f 0e 00 movsd 0xe6f(%rip),%xmm0 # 2010 <_ZStL19piecewise_construct+0x8> 11a0: 00 11a1: 48 8b 05 70 0e 00 00 mov 0xe70(%rip),%rax # 2018 <_ZStL19piecewise_construct+0x10> 11a8: 66 0f 28 c8 movapd %xmm0,%xmm1 11ac: 66 48 0f 6e c0 movq %rax,%xmm0 11b1: e8 87 00 00 00 callq 123d <_Z7compareIdEbT_S0_> // bool b3=compare<double>(1.0,2.0); double 类型的函数 11b6: 88 45 ff mov %al,-0x1(%rbp) 11b9: b8 01 00 00 00 mov $0x1,%eax 11be: c9 leaveq 11bf: c3 retq 00000000000011c0 <_Z41__static_initialization_and_destruction_0ii>: 11c0: f3 0f 1e fa endbr64 11c4: 55 push %rbp 11c5: 48 89 e5 mov %rsp,%rbp 11c8: 48 83 ec 10 sub $0x10,%rsp 11cc: 89 7d fc mov %edi,-0x4(%rbp) 11cf: 89 75 f8 mov %esi,-0x8(%rbp) 11d2: 83 7d fc 01 cmpl $0x1,-0x4(%rbp) 11d6: 75 32 jne 120a <_Z41__static_initialization_and_destruction_0ii+0x4a> 11d8: 81 7d f8 ff ff 00 00 cmpl $0xffff,-0x8(%rbp) 11df: 75 29 jne 120a <_Z41__static_initialization_and_destruction_0ii+0x4a> 11e1: 48 8d 3d 29 2e 00 00 lea 0x2e29(%rip),%rdi # 4011 <_ZStL8__ioinit> 11e8: e8 83 fe ff ff callq 1070 <_ZNSt8ios_base4InitC1Ev@plt> 11ed: 48 8d 15 14 2e 00 00 lea 0x2e14(%rip),%rdx # 4008 <__dso_handle> 11f4: 48 8d 35 16 2e 00 00 lea 0x2e16(%rip),%rsi # 4011 <_ZStL8__ioinit> 11fb: 48 8b 05 f6 2d 00 00 mov 0x2df6(%rip),%rax # 3ff8 <_ZNSt8ios_base4InitD1Ev@GLIBCXX_3.4> 1202: 48 89 c7 mov %rax,%rdi 1205: e8 56 fe ff ff callq 1060 <__cxa_atexit@plt> 120a: 90 nop 120b: c9 leaveq 120c: c3 retq 000000000000120d <_GLOBAL__sub_I_main>: 120d: f3 0f 1e fa endbr64 1211: 55 push %rbp 1212: 48 89 e5 mov %rsp,%rbp 1215: be ff ff 00 00 mov $0xffff,%esi 121a: bf 01 00 00 00 mov $0x1,%edi 121f: e8 9c ff ff ff callq 11c0 <_Z41__static_initialization_and_destruction_0ii> 1224: 5d pop %rbp 1225: c3 retq 0000000000001226 <_Z7compareIiEbT_S0_>: // compare<int>(int a, int b) 1226: f3 0f 1e fa endbr64 122a: 55 push %rbp 122b: 48 89 e5 mov %rsp,%rbp 122e: 89 7d fc mov %edi,-0x4(%rbp) 1231: 89 75 f8 mov %esi,-0x8(%rbp) 1234: 83 7d f8 00 cmpl $0x0,-0x8(%rbp) 1238: 0f 95 c0 setne %al 123b: 5d pop %rbp 123c: c3 retq 000000000000123d <_Z7compareIdEbT_S0_>: //compare<double>(1.0,2.0); double 类型的函数 123d: f3 0f 1e fa endbr64 1241: 55 push %rbp 1242: 48 89 e5 mov %rsp,%rbp 1245: f2 0f 11 45 f8 movsd %xmm0,-0x8(%rbp) 124a: f2 0f 11 4d f0 movsd %xmm1,-0x10(%rbp) 124f: 66 0f ef c0 pxor %xmm0,%xmm0 1253: 66 0f 2e 45 f0 ucomisd -0x10(%rbp),%xmm0 1258: 0f 9a c0 setp %al 125b: ba 01 00 00 00 mov $0x1,%edx 1260: 66 0f ef c0 pxor %xmm0,%xmm0 1264: 66 0f 2e 45 f0 ucomisd -0x10(%rbp),%xmm0 1269: 0f 45 c2 cmovne %edx,%eax 126c: 5d pop %rbp 126d: c3 retq 126e: 66 90 xchg %ax,%ax0000000000001270 <__libc_csu_init>: 1270: f3 0f 1e fa endbr64 1274: 41 57 push %r15 1276: 4c 8d 3d 13 2b 00 00 lea 0x2b13(%rip),%r15 # 3d90 <__frame_dummy_init_array_entry> 127d: 41 56 push %r14 127f: 49 89 d6 mov %rdx,%r14 1282: 41 55 push %r13 1284: 49 89 f5 mov %rsi,%r13 1287: 41 54 push %r12 1289: 41 89 fc mov %edi,%r12d 128c: 55 push %rbp 128d: 48 8d 2d 0c 2b 00 00 lea 0x2b0c(%rip),%rbp # 3da0 <__do_global_dtors_aux_fini_array_entry> 1294: 53 push %rbx 1295: 4c 29 fd sub %r15,%rbp 1298: 48 83 ec 08 sub $0x8,%rsp 129c: e8 5f fd ff ff callq 1000 <_init> 12a1: 48 c1 fd 03 sar $0x3,%rbp 12a5: 74 1f je 12c6 <__libc_csu_init+0x56> 12a7: 31 db xor %ebx,%ebx 12a9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 12b0: 4c 89 f2 mov %r14,%rdx 12b3: 4c 89 ee mov %r13,%rsi 12b6: 44 89 e7 mov %r12d,%edi 12b9: 41 ff 14 df callq *(%r15,%rbx,8) 12bd: 48 83 c3 01 add $0x1,%rbx 12c1: 48 39 dd cmp %rbx,%rbp 12c4: 75 ea jne 12b0 <__libc_csu_init+0x40> 12c6: 48 83 c4 08 add $0x8,%rsp 12ca: 5b pop %rbx 12cb: 5d pop %rbp 12cc: 41 5c pop %r12 12ce: 41 5d pop %r13 12d0: 41 5e pop %r14 12d2: 41 5f pop %r15 12d4: c3 retq 12d5: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 12dc: 00 00 00 00 00000000000012e0 <__libc_csu_fini>: 12e0: f3 0f 1e fa endbr64 12e4: c3 retq Disassembly of section .fini:00000000000012e8 <_fini>: 12e8: f3 0f 1e fa endbr64 12ec: 48 83 ec 08 sub $0x8,%rsp 12f0: 48 83 c4 08 add $0x8,%rsp 12f4: c3 retq如果compare(100,1.1) // 编译器推演失败 可以 comare(100,1.1);让编译器强转
函数模板是无法编译的,也不进行编译的,函数模板在调用点发生模板实例化动作,被实例化化后 成为模板函数,模板函数才是真正参与编译的
关于模板特例化如果有compare("aaa",bbb“”); 此时模板会自动推到出如下compare<const char *>(const char * x,const char * y){return x>y;}
上面的比较方式会去比较两个指针地址大小,这种方式不是我们想要的逻辑,所以我们需要根据const char * 写一个特殊的实现方法逻辑如下template<>bool compare<const char *>(const char *x ,const char * y){return strcmp(x,y);}那么上面这个函数就叫做模板的特例化 特例化特殊在不再由编译器自动生成函数,使用自己的实现方式
普通函数和函数模板选择问题 示例代码
点击查看代码如果有//这是个函数模板template<>bool compare<const char *>(const char *x ,const char * y){ return strcmp(x,y);}//这是一个普通的函数bool compare(const char *x ,const char * y){ return strcmp(x,y);}有bool b=compare("aa","bb");//那么编译器会优选能匹配的普通的函数,避免编译器再去生成函数bool b1=compare<const char *>("aa","bb");//这个时候会使用模板特例化//所以我们会遇到 函数模板, 模板特例化, 普通函数都可以匹配调用的时候,如何选择需要知道,自动推演有普通函数能用的,用普通函数,没有普通函数如果有模板特例化的用特例化,没有特例化的,编译器去生成指定类型函数下面我们看一下模板和调用点分文件编写遇到的问题
只有函数模板,编译后查看符号表情况,点击查看代码// test1.cpp 代码如下#include <iostream>#include <cstring>using namespace std;//这是一个函数模板template<typename T>bool compare(T x,T y){ return x,y;}//test1.cpp 编译后 符号表情况如下,编译后没有 函数符号uos20@uos20-PC:~/Desktop/CPP$ g++ -c test1.cpp -o test1.o -guos20@uos20-PC:~/Desktop/CPP$ objdump -t test1.otest1.o: 文件格式 elf64-x86-64SYMBOL TABLE:0000000000000000 l df *ABS* 0000000000000000 test1.cpp0000000000000000 l d .text 0000000000000000 .text0000000000000000 l d .data 0000000000000000 .data0000000000000000 l d .bss 0000000000000000 .bss0000000000000000 l d .rodata 0000000000000000 .rodata0000000000000000 l O .rodata 0000000000000001 _ZStL19piecewise_construct0000000000000000 l O .bss 0000000000000001 _ZStL8__ioinit0000000000000000 l F .text 000000000000003e _Z41__static_initialization_and_destruction_0ii000000000000003e l F .text 0000000000000015 _GLOBAL__sub_I_test1.cpp0000000000000000 l d .init_array 0000000000000000 .init_array0000000000000000 l d .debug_info 0000000000000000 .debug_info0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges0000000000000000 l d .debug_line 0000000000000000 .debug_line0000000000000000 l d .debug_str 0000000000000000 .debug_str0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack0000000000000000 l d .eh_frame 0000000000000000 .eh_frame0000000000000000 l d .comment 0000000000000000 .comment0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev0000000000000000 *UND* 0000000000000000 .hidden __dso_handle0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev0000000000000000 *UND* 0000000000000000 __cxa_atexit有函数模板及一个特例化,编译后查看符号表情况,点击查看代码// test1.cpp 代码如下#include <iostream>#include <cstring>using namespace std;//这是一个函数模板template<typename T>bool compare(T x,T y){ return x,y;}//模板特例化template<>bool compare(const char * x, const char * y){ return strcmp(x,y);}//test1.cpp 编译后 符号表情况如下,编译后没有 函数符号uos20@uos20-PC:~/Desktop/CPP$ g++ -c test1.cpp -o test1.o -guos20@uos20-PC:~/Desktop/CPP$ objdump -t test1.otest1.o: 文件格式 elf64-x86-64SYMBOL TABLE:0000000000000000 l df *ABS* 0000000000000000 test1.cpp0000000000000000 l d .text 0000000000000000 .text0000000000000000 l d .data 0000000000000000 .data0000000000000000 l d .bss 0000000000000000 .bss0000000000000000 l d .rodata 0000000000000000 .rodata0000000000000000 l O .rodata 0000000000000001 _ZStL19piecewise_construct0000000000000000 l O .bss 0000000000000001 _ZStL8__ioinit000000000000002a l F .text 000000000000003e _Z41__static_initialization_and_destruction_0ii0000000000000068 l F .text 0000000000000015 _GLOBAL__sub_I__Z7compareIPKcEbT_S2_ // 特例化函数符号compare0000000000000000 l d .init_array 0000000000000000 .init_array0000000000000000 l d .debug_info 0000000000000000 .debug_info0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges0000000000000000 l d .debug_line 0000000000000000 .debug_line0000000000000000 l d .debug_str 0000000000000000 .debug_str0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack0000000000000000 l d .eh_frame 0000000000000000 .eh_frame0000000000000000 l d .comment 0000000000000000 .comment0000000000000000 g F .text 000000000000002a _Z7compareIPKcEbT_S2_0000000000000000 *UND* 0000000000000000 strcmp0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev0000000000000000 *UND* 0000000000000000 .hidden __dso_handle0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev0000000000000000 *UND* 0000000000000000 __cxa_atexit有函数模板及一个特例化和一个普通函数,编译后查看符号表情况,点击查看代码// test1.cpp 代码如下#include <iostream>#include <cstring>using namespace std;//这是一个函数模板template<typename T>bool compare(T x,T y){ return x,y;}//模板特例化template<>bool compare(const char * x, const char * y){ return strcmp(x,y);}//这是一个普通的函数,不是模板,与模板无关bool compare( const char * x, const char * y){ return x>y;}//编译完成后,我们再符号表中 看到两处 compare ,一处是特例化,一处是 普通compare函数uos20@uos20-PC:~/Desktop/CPP$ g++ -c test1.cpp -o test1.o -guos20@uos20-PC:~/Desktop/CPP$ objdump -t test1.otest1.o: 文件格式 elf64-x86-64SYMBOL TABLE:0000000000000000 l df *ABS* 0000000000000000 test1.cpp0000000000000000 l d .text 0000000000000000 .text0000000000000000 l d .data 0000000000000000 .data0000000000000000 l d .bss 0000000000000000 .bss0000000000000000 l d .rodata 0000000000000000 .rodata0000000000000000 l O .rodata 0000000000000001 _ZStL19piecewise_construct0000000000000000 l O .bss 0000000000000001 _ZStL8__ioinit0000000000000043 l F .text 000000000000003e _Z41__static_initialization_and_destruction_0ii0000000000000081 l F .text 0000000000000015 _GLOBAL__sub_I__Z7compareIPKcEbT_S2_0000000000000000 l d .init_array 0000000000000000 .init_array0000000000000000 l d .debug_info 0000000000000000 .debug_info0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges0000000000000000 l d .debug_line 0000000000000000 .debug_line0000000000000000 l d .debug_str 0000000000000000 .debug_str0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack0000000000000000 l d .eh_frame 0000000000000000 .eh_frame0000000000000000 l d .comment 0000000000000000 .comment0000000000000000 g F .text 000000000000002a _Z7compareIPKcEbT_S2_ //compare 函数符号0000000000000000 *UND* 0000000000000000 strcmp000000000000002a g F .text 0000000000000019 _Z7comparePKcS0_ //compare函数符号0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev0000000000000000 *UND* 0000000000000000 .hidden __dso_handle0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev0000000000000000 *UND* 0000000000000000 __cxa_atexit分文件编写,测试代码1,点击查看代码// test1.cpp#include <iostream>#include <cstring>using namespace std;//这是一个函数模板template<typename T>bool compare(T x,T y){ return x,y;}//test2.cpp#include <iostream>#include <cstring>using namespace std;template<typename T>bool compare(T x, T y);int main() { bool b1 = compare<int>(1, 2); bool b2 = compare<double>(100.1, 200.1); return 1;}// 编译 报 两处错 //无法解析的外部符号 "bool __cdecl compare<double>(double,double)//无法解析的外部符号 "bool __cdecl compare<int>(int,int)//为什么会出现链接错误?我先看一下test2.cpp编译后的符号表情况 如下uos20@uos20-PC:~/Desktop/CPP$ g++ -c test2.cpp -o test2.o -guos20@uos20-PC:~/Desktop/CPP$ objdump -t test2.otest2.o: 文件格式 elf64-x86-64SYMBOL TABLE:0000000000000000 l df *ABS* 0000000000000000 test2.cpp0000000000000000 l d .text 0000000000000000 .text0000000000000000 l d .data 0000000000000000 .data0000000000000000 l d .bss 0000000000000000 .bss0000000000000000 l d .rodata 0000000000000000 .rodata0000000000000000 l O .rodata 0000000000000001 _ZStL19piecewise_construct0000000000000000 l O .bss 0000000000000001 _ZStL8__ioinit0000000000000039 l F .text 000000000000003e _Z41__static_initialization_and_destruction_0ii0000000000000077 l F .text 0000000000000015 _GLOBAL__sub_I_main0000000000000000 l d .init_array 0000000000000000 .init_array0000000000000000 l d .debug_info 0000000000000000 .debug_info0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges0000000000000000 l d .debug_line 0000000000000000 .debug_line0000000000000000 l d .debug_str 0000000000000000 .debug_str0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack0000000000000000 l d .eh_frame 0000000000000000 .eh_frame0000000000000000 l d .comment 0000000000000000 .comment0000000000000000 g F .text 0000000000000039 main0000000000000000 *UND* 0000000000000000 _Z7compareIiEbT_S0_ //compare<int> 函数符号 UND形式0000000000000000 *UND* 0000000000000000 _Z7compareIdEbT_S0_ //compare<double> 函数符号 UND形式0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitC1Ev0000000000000000 *UND* 0000000000000000 .hidden __dso_handle0000000000000000 *UND* 0000000000000000 _ZNSt8ios_base4InitD1Ev0000000000000000 *UND* 0000000000000000 __cxa_atexit//test2.cpp 和 test1.cpp 分离编译,test2.cpp 有 compare<int>函数符号 UND(外部引用) 和 compare<double>函数符号 UND(外部引用)//然而test1.cpp只是模板 编译时 没有 compare<int>(int a,int b) 和compare<double>(double a, double b)产生编译,//所以链接的时候,test2.o 的 UND函数需要去其他目标文件中找compare<int>(int a, int b)和compare<double>(double a, double b)的定义,找不到,编译报错分文件编写,测试代码2,点击查看代码// test1.cpp#include <iostream>#include <cstring>using namespace std;//这是一个函数模板template<typename T>bool compare(T x,T y){ return x,y;}//模板特例化template<>bool compare<const char *>(const char * x, const char * y) {return strcmp(x, y);}//test2.cpp#include <iostream>#include <cstring>using namespace std;template<typename T>bool compare(T x, T y);int main() { bool b3 = compare("aaa", "bbb"); return 1;}//正常编译通过并调用分文件编写,测试代码3 ,点击查看代码//test1.cpp#include <iostream>#include <cstring>using namespace std;//这是一个函数模板template<typename T>bool compare(T x, T y) {return x, y;}//模板特例化template<>bool compare<const char *>(const char * x, const char * y) {cout << "Template Function" << endl;return strcmp(x, y);}//这是一个普通的函数,不是模板,与模板无关bool compare(const char * x, const char * y) {cout << "Normal Function" << endl;return x>y;}//test2.cpp#include <iostream>#include <cstring>using namespace std;template<typename T>bool compare(T x, T y);bool compare(const char * x, const char * y);int main() { bool b3 = compare("aaa", "bbb"); return 1;}//正常编译通过,调用普通函数分文件编写,测试代码4,点击查看代码// test1.cpp#include <iostream>#include <cstring>using namespace std;//这是一个函数模板template<typename T>bool compare(T x, T y) {return x, y;}//模板特例化template<>bool compare<const char *>(const char * x, const char * y) {cout << "Template Function" << endl;return strcmp(x, y);}//这是一个普通的函数,不是模板,与模板无关bool compare(const char * x, const char * y) {cout << "Normal Function" << endl;return x>y;}//编译后, .o文件中有两处 compare函数符号,一处是 普通函数的,一处是 模板特例化函数的// test2.cpp 情况1 下面test2.cpp编译后,.o文件中没有compare函数符号#include <iostream>#include <cstring>using namespace std;//模板上一篇:2022年最新苹果CMSV10电影先生6.1.1模板破解版整站打包15W加数据-破解(2022年最新苹果平板电脑)
友情链接: 武汉网站建设