模板的显示实例化与显示具体化

2023-11-01

显式实例化:
C++中模板函数(类)的调用与定义分离时,需要使用显式实例化,否则就会出现链接错误。
编译器对各个cpp分别编译的时候,模板函数必须被实例化编译。如果我们把调用与定义写在一个文件,在调用语句处有int a, b; cmp(a, b); 那么编译器就会知道我们将要使用cmp,然后结合该模板函数的定义语句,最后就编译出这么一个函数。问题就出现在我们把调用与定义写在不同的文件里,当编译器编译定义函数的cpp的时候,即便这个cpp有include该模板函数的头文件,编译器仍然不知道你的实例化typename是什么,因此这个.o就不会含实例化的函数。而编译器编译调用函数的cpp的时候,即便这个cpp也include了函数的头文件,但是由于没有定义,这个.o也不含实例化的函数。最后链接该定义cpp的.o和调用cpp的.o的时候,会找不到相应的实例化函数而报错。

//Example.h
template<class T>
class Test {
    public:
        Do(T a);
};
 
//Example.cpp
#include "Example.h"
 
template<class T>
Test::Do(T a) {
    //do nothing...
}
 
//template class Test<int>;   //注意显示实例化的语法,用<>符号指示类型

当保留最后一行的时候,编译Example.cpp输出汇编语言会得到一大块东西,而注释掉最后一行后就只剩下
.file “Example.cpp”
.ident “GCC: (tdm64-2) 4.8.1”
显然是没有代码被生成的,调用cpp产生的.o在链接example.o的时候就会出现链接错误。

显式具体化:
假设定义了如下结构:
struct job
{
char name[40];
double salary;
int floor;
};
另外,假设希望能够交换两个这种结构的内容。原来的模板使用下面的代码来完成交换:
temp = a;
a = b;
b = temp;
原来的模板使用下面的代码来完成交换, 它只能完成int,float等常规类型变量的交换,而如果是自定义的复杂结构体,则无法处理。因此类似于重载一样,我们要具体化一个特例template<> void Swap(job &j1, job &j2):

template<typename T>
void Swap(T &a, T &b)
{
    T temp;
    temp = a;
    a = b;
    b = temp;
}
template<> void Swap<job>(job &j1, job &j2)//显式具体化在关键字template后包含<>,而显式实例化没有
{
    double t1;
    int t2;
    t1 = j1.salary;
    j1.salary = j2.salary;
    j2.salary = t1;
    t2 = j1.floor;
    j1.floor = j2.floor;
    j2.floor = t2;
}
void Show(job &j)
{
    cout << j.name << ": $" << j.salary
         << " on floor " << j.floor << endl;
}
int main()
{
    cout.precision(2);
    cout.setf(ios::fixed, ios::floatfield);
    int i = 10, j = 20;
    cout << "i, j = " << i << ", " << j << ".\n";
    cout << "Using compiler-generated int swapper:\n";
    Swap(i, j);
    cout << "Now i, j = " << i << ", " << j << ".\n\n";
 
    job sue = {"Susan Yaffee", 73000.60, 7};
    job sidney = {"Sidney Taffee", 78060.72, 9};
    cout << "Before job swapping:\n";
    Show(sue);
    Show(sidney);
    Swap(sue, sidney);
    cout << "After job swapping:\n";
    Show(sue);
    Show(sidney);
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模板的显示实例化与显示具体化 的相关文章

随机推荐

  • linux部署项目

    linux部署项目 一 安装jdk 1 二 安装tomcat 1 官网下载tomcat 官网地址 https tomcat apache org 2 部署项目 将下载的tomcat文件放入linux文件夹下 输入命令 tar zxvf ap
  • 离线pip安装paddlepaddle时存在的问题

    由于内网限制 只能从清华源安装软件包 而清华源没有满足条件的paddlepaddle安装包 为了成功在内网环境安装paddlepaddle 可以按照如下步骤 在开始使用 飞桨 源于产业实践的开源深度学习平台 官网平台 按照操作系统 计算平台
  • JDBC数据库连接 及JDBC使用讲解

    目录 1 什么是JDBC 2 JDBC 作原理 3 JDBC 使 3 1 创建项目并添加MySQL驱动 DataSource实现操作数据库 3 2 使用代码操作数据库 1 什么是JDBC Java 数据库连接 是 种 于执 SQL 语句的
  • 用Python编写代码,实现输出自己的姓名,班级,学号等信息

    可以使用以下代码实现输出自己的姓名 班级 学号等信息 name 你的姓名 class name 你的班级 student id 你的学号 print 姓名 name print 班级 class name print 学号 student
  • shell-环境变量以及环境变量的配置文件

    环境变量定义 用户自定义变量只在当前的shell中生效 而环境变量会在当前shell和这个shell的所有子shell当中生效 如果把环境变量写入相应的配置文件 那么这个环境变量就会在所有的shell中生效 设置环境变量 export 变量
  • Unity Shader小技巧-制作Shader时在Scene显示实时动态效果

    直接上截图 在编辑shader时 我们会使用到很多动态效果 例如 Time的函数 但是在Unity中会是静态效果 点击这个选项之后就以看到Scene窗口的Shader有动态效果了
  • malloc函数的使用

    调用被调函数 将主函数中动态内存分配的内存中的数据放大十倍 malloc动态分配了1字节的内存空间 最多能存放的整数是255 int型变量并不是一定占4字节 C语言从来没有规定一个整型必须要强制占几字节 C语言只规定了 短整型的长度不能大于
  • ASP.net DropDownList数据绑定及使用详解

    1 dropdownlist 绑定数据 1 1 固定绑定 适合已经固定的数据绑定到dropdownlist 实例
  • vue3中知识点总结(持续更新)

    1 具名插槽 Vue3 具名插槽 Named Slots 文档地址 具名插槽添加
  • java并发怎么理解_java中并发的理解

    在java中谈到并发 我们一定会想到两种锁 一种synchronized锁 一种ReentrantLock 还有一种轻量级的作用在变量上的volatile 那么他们三个有什么具体区别 和具体怎么用呢 下面针对他们三个分别说一下原理和作用 v
  • ArcGIS 正高转换成椭球体高度

    转载 https resources arcgis com zh cn help main 10 1 index html 009t000001vm000000 一 椭球体高度与正高 具体讲解可见 https resources arcgi
  • Fabric加密算法

    BCCSP Blockchain crypto provider 即区块链加密提供商 用于定义选择使用的密码学实现库 负责摘要生成 非对称密钥的签名与验证 根据证书查找私钥等 该模块提供了一系列的接口 这些接口定义了摘要的生成方法 签名 验
  • 负载均衡之Keepalived

    严格意义来说 Keepalived主要是通过虚拟路由冗余来实现高可用功能 但是其也可以借助IPVS实现负载均衡 所以也简要的学习了一下 简介 起初是设计来监控集群中各个节点的状态 根据TCP IP模型中网络层 ICMP控制消息请求 传输层
  • QFileInfo

    一 描述 QFileInfo 提供有关文件系统中文件的名称和位置 路径 访问权限 文件类型等信息 FileInfo 还可用于获取有关 Qt 资源的信息 这个类是隐式共享的 二 成员函数 2 1 判断函数 1 bool isAbsolute
  • python_sqlalchemy

    SQLAlchemy使用和踩坑记 知乎 2 长时间未请求连接自动断开 现象 长时间服务端没有连接数据库 数据库连接自动断开 原因 1 sqlalchemy在create engine时 使用连接池并没有指定连接池回收时间 则连接池的连接不会
  • 交互设计实用指南系列(1) – 操作入口明确

    链接 http ued taobao org blog 2009 12 the practice guidelines of interaction design clear operational entrance of effectiv
  • 微软 AD 已成过去式,这个身份领域国产化替代方案你了解吗?

    随着全球互联网和数字化浪潮的不断发展 信息安全已成为不可忽视的问题 并随着日益复杂的国内外市场格局 其重要性更加凸显 我国政府也相继印发和实施了 数字中国建设整体布局规划 全国一体化大数据体系建设指南 等一系列政策 将核心技术自主可控 安全
  • CSS学习————css的选择器(2)

    选择器的作用 用来查找要设置html样式的元素 css的选择器分为4大类 1 简单选择器 6种 1 1 通配符选择器 1 2 标签选择器 1 3 id选择器 1 4 属性选择器 1 5 类选择器 1 6 分组选择器
  • Mac OS X下Android系统华为手机无法连接问题之解决方案

    一般的android连接mac 很方便不用安装驱动就可以啦 可是不知道为什么特殊情况下有的android手机 小米2 华为等 就是连接不上 下来就说说特殊情况下如何连接 使用USB连接安卓手机后可以做2件事情 关于本机 gt 更多信息 gt
  • 模板的显示实例化与显示具体化

    显式实例化 C 中模板函数 类 的调用与定义分离时 需要使用显式实例化 否则就会出现链接错误 编译器对各个cpp分别编译的时候 模板函数必须被实例化编译 如果我们把调用与定义写在一个文件 在调用语句处有int a b cmp a b 那么编