C++模板得实例化

栏目: C++ · 发布时间: 6年前

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

[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?


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

架构即未来:现代企业可扩展的Web架构、流程和组织(原书第2版)

架构即未来:现代企业可扩展的Web架构、流程和组织(原书第2版)

Martin L. Abbott、Michael T. Fisher / 陈斌 / 机械工业出版社 / 2016-4-15 / 99.00

任何一个持续成长的公司最终都需要解决系统、组织和流程的扩展性问题。本书汇聚了作者从eBay、VISA、Salesforce.com到Apple超过30年的丰富经验, 全面阐释了经过验证的信息技术扩展方法,对所需要掌握的产品和服务的平滑扩展做了详尽的论述,并在第1版的基础上更新了扩展的策略、技术和案例。 针对技术和非技术的决策者,马丁•阿伯特和迈克尔•费舍尔详尽地介绍了影响扩展性的各个方面,包......一起来看看 《架构即未来:现代企业可扩展的Web架构、流程和组织(原书第2版)》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换