63

C++模板得实例化

 5 years ago
source link: http://pkxpp.github.io/2019/01/18/c 模板得实例化/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

[TOC]

问题描述

在stackoverflow看到一个问题,说重载函数试根据参数来的,和返回类型没有关系。然而下面这个模板函数只有返回类型不一样,为什么是正确的,参考[1]。

#include <iostream>
using namespace std;

template<typename T>
T add(double a, double b)
{
    return static_cast<T>(a + b); 
}

int main()
{
    cout << add<int>(1.1, 1) << endl;
    cout << add<double>(1.1, 1) << endl;
    return 0;
}

这个代码正确,这说明 add<int>(double, double)add<double>(double, double) 这两个函数的符号是不一样的。那么这和模板代码的生成有关,模板其实是在使用的时候会生成一份指定类型的代码的,也就是模板的实例化。 有人给出了详细的答案,贴在这里: 返回类型并不是函数前面的一部分,c++标准规定:defns.signature

(function) name, parameter-type-list, and enclosing namespace (if any) [ Note: Signatures are used as a basis for name mangling and linking. — end note ]

但是模板函数的前面是包含模板参数的:defns.signature.spec

(function) template specialization⟩ signature of the template of which it is a specialization and its template arguments (whether explicitly specified or deduced)

抛开问题,现在来看看模板的实例化。

模板的实例化

测试代码test.cpp:

template < class T> T add(T a, T b){
            return a+b;
}
void tmp(){
 add<int>(10, 2);
}
int add(int a, int b)
{
 return a + b;
}
  • 查看汇编代码

指令:

gcc -S -O1 test.cpp

得到代码如下所示(部分):

// 模板函数
_Z3addIiET_S0_S0_:
.LFB3:
 .cfi_startproc
 pushq	%rbp

// 普通add函数
_Z3addii:
.LFB2:
 .cfi_startproc
 pushq	%rbp

使用c++filt查看如下:

[root@localhost template]# c++filt _Z3addIiET_S0_S0_
int add<int>(int, int)
[root@localhost template]# c++filt _Z3addii
add(int, int)
  • 使用clang的功能得到如下内容,也可以看出生成了一份和普通函数不一样的函数前面
[root@localhost template]# clang++ -Xclang -ast-print -fsyntax-only compile2.cpp
template <class T = int> int add(int a, int b) {
    return a + b;
}
template <class T> T add(T a, T b) {
    return a + b;
}
;
void tmp() {
    add<int>(10, 2);
}
int add(int a, int b) {
    return a + b;
}

总结

  • 模板函数会为实例化不同类型,生成不同的函数代码
  • 模板函数的函数前面是带了模板参数的,所以和普通函数前面不一样,即使名字和参数类型以及个数都一样

参考

[1] Why template function only base the return type works on C++?

[2] Template Compilation

[3] Can we see the template instantiated code by C++ compiler

[4] Will C++ compiler generate code for each template type?

[5] How do I find how C++ compiler implements something except inspecting emitted machine code?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK