今天编码的时候,发现了一个错误,就是模板代码在链接的时候找不到方法。

情况大概如下:

在 "Manager.h" 中

class Manager {

public:

  template<typename T>

  void SetData(const T& value);

};

然后在cpp文件中定义SetData

template<typename T>

void Manager::SetData(const T& value) {

}

在另外一个main.cpp文件中使用

#include "Manager.h"

Manager mgr;

double n = 0;

mgr.SetData(n);

这样就会产生一个error LNK2019:无法解析的外部符号 “public: void __thiscall Manager::SetData<double>(const double&)” xxxx,该符号在 xx函数中被引用的链接错误。查了一下书籍,错误的原因在于,function template SetData(const T&)的定义没有具现化,Manager.h和Manager.cpp是分开编译的,在编译main.cpp的过程中,编译器假设这个template的定义在某个地方,因而只生成一个对该定义的reference,并将这个reference所指的定义式留给链接器去决议,但是在链接期间,又找不到这样一个定义。

Note:奇怪的是,如果n是int类型,又可以编译成功,但是回家后,我用自己的电脑试了一下,VS2008,int类型的也不行

解决这个问题有几个方法:

1)采用置入式。也就是定义也放在头文件中

2)显示具现化一份声明。

即在cpp文件中声明如下 template void Manager::SetData(const double&); ,这样做就要为每一个类型做一份声明,比较繁琐

3)采用export关键字。它会export出除inline之外的其他方法

export template <typename T>

class Manager {

public:

  void SetData(const T&); //这个声明就会被export

  void Print() {}; //不会被export

};

C++ template 声明与定义的更多相关文章

  1. c++函数模板声明与定义相分离

    最近在仿写stl,发现stl源码中将模板的声明与定义写在一起实在很不优雅.自己尝试用“传统”方法,及在.h文件里声明,在.cpp文件里定义,然后在main函数里包含.h头文件,这样会报链接错误.这是因 ...

  2. C++声明和定义

    目录 1 参考 2 概念 2.1 声明 2.2 定义 3 对比 3.1 声明但不是定义的情况 3.2 声明且是定义的情况 3.3 特殊情况 1. 参考 1. <C++程序设计语言>4.9 ...

  3. c++模板类成员的声明和定义

    c++模板类成员的声明和定义应该都放在*.h中,有普通类不一样. 如果定义放在*.cpp中,最终链接时,会报方法undefined错误. 参考:http://users.cis.fiu.edu/~we ...

  4. 为什么 c++中函数模板和类模板的 声明与定义需要放到一起?

    将模板的声明与定义写在一起实在很不优雅.尝试用“传统”方法,及在.h文件里声明,在.cpp文件里定义, 然后在main函数里包含.h头文件,这样会报链接错误.why!!!!!!!!!!!!! 这是因为 ...

  5. Error LNK2019: unresolved external symbol C++模板类声明与定义链接错误问题

    编译器在编译模板时,并不会生成代码,只有遇到实例化的时候才会生成代码.因此,当我们只引用模板声明文件的时候,在实例化的对象时候,模板的定义问文件是不可见的,于是出现链接错误.例如: //A.h #pr ...

  6. C++将模板的声明和定义放置在同一个头文件里

    1. 一个类: 头文件用于保存类的声明:定义文件保存类的实现.   2. 分离编译模式: 允许在一个编译单元(.cpp文件)中定义函数.类型.类对象等,然后在另一个编译单元中引用它们.编译器处理完所有 ...

  7. C++类模板声明与定义为何不能分开

    我们用C++写类的时候,通常会将.cpp和.h文件分开写,即实现和声明分开写了:但在C++的类模板中,这种写法是错误的. 在<C++编程思想>的第16章的"16.3模板语法&qu ...

  8. C++中重定义的问题——问题的实质是声明和定义的关系以及分离式编译的原理

    这里的问题实质是我们在头文件中直接定义全局变量或者函数,却分别在主函数和对应的cpp文件中包含了两次,于是在编译的时候这个变量或者函数被定义了两次,问题就出现了,因此,我们应该形成一种编码风格,即: ...

  9. C\C++中声明与定义的区别

    声明和定义是完全同的概念,声明是告诉编译器"这个函数或者变量可以在哪找到,它的模样像什么".而定义则是告诉编译器,"在这里建立变量或函数",并且为它们分配内存空 ...

随机推荐

  1. qb64手记(2)

    传值与传引用 PRINT mymax(12, 111) x1 = 55x2 = 66myswapPRINT x1 FUNCTION mymax (x, y)IF x > y THEN    my ...

  2. swagger api 文档框架

    <其他教程:https://www.cnblogs.com/FlyAway2013/p/7510279.html> 先看看swagger的生态使用图: 其中,红颜色的是swaggger官网 ...

  3. 【BZOJ3784】树上的路径 点分治序+ST表

    [BZOJ3784]树上的路径 Description 给定一个N个结点的树,结点用正整数1..N编号.每条边有一个正整数权值.用d(a,b)表示从结点a到结点b路边上经过边的权值.其中要求a< ...

  4. Bag of mice(概率DP)

    Bag of mice  CodeForces - 148D The dragon and the princess are arguing about what to do on the New Y ...

  5. 微信H5支付开发步骤总结

    * 开发步骤: * 1.在微信公众号平台设置授权目录,即jsapi.php所在的目录 * 2.在微信支付平台下载证书,放到cert目录 * 3.在微信支付平台设置API秘钥,同时在WxPay.Conf ...

  6. Java基础 - 输出

    输出在各个开发语言中起着至关重要的作用,方便编写代码时进行调试,在java中使用 System.out.println 进行输出 public class Main { public static v ...

  7. zabbix server 端安装

    1.系统环境 [root@crazy-acong ~]# cat /etc/redhat-release CentOS release 6.6 (Final) [root@crazy-acong ~] ...

  8. Qt状态机框架(状态机就开始异步的运行了,也就是说,它成为了我们应用程序事件循环的一部分了)

    状态机框架 Qt中的状态机框架为我们提供了很多的API和类,使我们能更容易的在自己的应用程序中集成状态动画.这个框架是和Qt的元对象系统机密结合在一起的.比如,各个状态之间的转换是通过信号触发的,状态 ...

  9. Java语言实现简单FTP软件------>连接管理模块的实现:主机与服务器之间的连接与关闭操作(八)

    (1)FTP连接 运行FTP客户端后,首先是连接FTP服务器,需要输入FTP服务器的IP地址及用户名.密码以及端口号后点击连接按钮开始连接FTP服务器,连接流程图如下图所示. 点击"连接&q ...

  10. 我的Android进阶之旅------>Android自定义窗口标题实例

    该实例的功能比较简单,但是通过该实例的扩展可以在自定义标题中做出菜单导航等实用的功能,为了实现自定义窗口标题,需要做以下几个步骤: 1.给自定义标题提供一个界面 2.将自定义标题应用给Activity ...