关闭

在写类模板时总是出error LNK2019: unresolved external symbol的原因

标签: error LNK2019vc++template
664人阅读 评论(0) 收藏 举报
分类:

最近在将代码改成模板时出现一堆的error LNK2019: unresolved external symbol错误;

百度才发现类模板的声明和实现不能分开,要放在一个文件中,引用百度的说明原因;

“通常情况下,你会在.h文件中声明函数和类,而将它们的定义放置在一个单独的.cpp文件中。但是在使用模板时,这种习惯性做法将变得不再有用,因为当实例化一个模板时,编译器必须看到模板确切的定义,而不仅仅是它的声明。因此,最好的办法就是将模板的声明和定义都放置在同一个.h文件中。这就是为什么所有的STL头文件都包含模板定义的原因。”[1]

"标准要求编译器在实例化模板时必须在上下文中可以查看到其定义实体;而反过来,在看到实例化模板之前,编译器对模板的定义体是不处理的——原因很简单,编译器怎么会预先知道 typename 实参是什么呢?因此模板的实例化与定义体必须放到同一翻译单元中。"[1]


"《C++编程思想》第15章(第300页)说明了原因:
模板定义很特殊。由template<…> 处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。
"[2]


"对C++编译器而言,当调用函数的时候,编译器只需要看到函数的声明。当定义类类型的对象时,编译器只需要知道类的定义,而不需要知道类的实现代码。因此,因该将类的定义和函数声明放在头文件中,而普通函数和类成员函数的定义放在源文件中。
       但在处理模板函数和类模板时,问题发生了变化。要进行实例化模板函数和类模板,要求编译器在实例化模板时必须在上下文中可以查看到其定义实体;而反过来,在看到实例化模板之前,编译器对模板的定义体是不处理的——原因很简单,编译器怎么会预先知道 typename 实参是什么呢?因此模板的实例化与定义体必须放到同一翻译单元中。
"[3]


一长串,没怎么看明白,直接看怎么弄吧  

 以下是模板声明和定义的两种方法:
1)可以通过在声明函数模板或类模板的头文件中添加一条#indlude指示定义可用,引入了包含相关定义的源文件。

//CANNBINARYBMP.H头文件

#pragma once
template<class T>
class CImageTemplate
{
protected:
private:
//function
bool isLineTransparent(CPOINT p1,CPOINT p2,bool bIsXLine);
T* catch_mode(CATCHMODE sCatchMode);
bool match_value(T *bpSPoint,int *pDposition,T *bpModeValue);
public:
void SlopeAdjust(double Slope);
float CalculateSlopebyHough();
VOID ImageDataConstruct(T w,T h);
};
#include "CANNBINARYBMP.cpp"
//<--------------------------添加这句把实现的CPP加进来
typedef CImageTemplate<INT> Cbinarybmp;


但这样又会引来"error C2995: 'CImageTemplate<T>::CImageTemplate(void)' : function template has already been defined"一堆以定义,这个可以处理下CPP文件如下:

#include "stdafx.h"
#ifndef _CANNCPP_//<--------------------------添加这句把实现的CPP加进来
#define _CANNCPP_

//cpp.源代码.....

#endif//<--------------------------添加这句把实现的CPP加进来

2)通过关键字export实现。
          C++理论上支持模板的分离编译(也就是支持export关键词),但是实际上VC2005,vs2010均不支持,在 VS 2008 中,export 关键字在 IDE 中被标蓝,表示 VS IDE 认识它,而编译时,会用警告友情提示你“不支持该关键字”。
3)当然就是将定义和实现文件写在一个文件中。

引用:"类模板和模板函数连接出错处理. http://www.cppblog.com/kenny/archive/2011/04/23/144841.html"

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

连接库的问题

先看一下错误吧,之前在debug下编译时没有问题的,但在release下时有问题的: : error LNK2019: unresolved external symbol _strlen refe...
  • joimson
  • joimson
  • 2013-08-13 11:15
  • 4326

mysql的安装、C++访问mysql数据库、编码设置问题

一.mysql的安装,这个相对简单,直接去官网下载mysql安装程序,就可以完成安装过程,网上有很多安装教程,这个没什么注意事项。   二、C++访问mysql,主要是用到mysql定义的头文件,内部...
  • IAccepted
  • IAccepted
  • 2014-06-21 17:30
  • 5709

Matlab 生成mexwin64文件时遇到的问题

近期下了一个matlab的 人体上半身探测的工具包calvin_upperbody_detector_v1.04,由于其本身是在linux下直接使用的,搬到win7上出现了一点问题。 在使用...
  • catherine627
  • catherine627
  • 2015-09-09 11:30
  • 2198

GPU编程之GLSL(附加一)——常见问题

如果在运行时出现如下问题: 1>ogl3.obj : error LNK2001: 无法解析的外部符号 __imp____glewGetShaderInfoLog 1>ogl3.obj : err...
  • Sun7_She
  • Sun7_She
  • 2014-08-15 09:58
  • 1274

libcurl.lib 导入问题 须知

vc2008构建和使用libcurl静态库 http://blog.csdn.net/mos2046/article/details/7697530 1>下载CURL源代码curl...
  • bible521125
  • bible521125
  • 2015-11-17 17:11
  • 1940

解决OpenSSL 在VC2015下链接报错的问题。

起因: 公司项目 服务器的nginx是使用的定制版,使用了concat、缩略图生成等模块,为了方便同事们在办公室环境下使用nginx,在Windows下编译nginx,并带上这两个模块。之前在 VC2...
  • bywayboy
  • bywayboy
  • 2015-10-07 11:05
  • 7988

在vs2013上运行OpenGL编程指南第8版第一个程序

本文主要解决vs2013下运行OpenGL编程指南第八版第一个程序的出错问题
  • u011517139
  • u011517139
  • 2017-06-05 20:21
  • 99

vs2013编译apr时遇到的疑难杂症

以下内容转自:http://nohup.yne.fr/2014/07/apache-22-msvc-2013.html Apache 2.2 & MSVC 2013 L...
  • fm0517
  • fm0517
  • 2015-04-23 19:37
  • 3589

SQLite学习笔记之三

一.如何备份数据库 先打开数据库test.db E:\sqlite\tool\sqlite-3_6_22>sqlite3  D:\Test\debug\test.db sqlite> .back...
  • snihcel
  • snihcel
  • 2013-04-07 10:35
  • 672

unresolved external symbol “symbol”(不确定的外部“符号”)。

unresolved external symbol “symbol”(不确定的外部“符号”)。   如果连接程序不能在所有的库和目标文件内找到所引用的函数、变量或标签,将产生此错误消息。一般来说,...
  • zcc1414
  • zcc1414
  • 2013-09-26 21:51
  • 508
    个人资料
    • 访问:113920次
    • 积分:1957
    • 等级:
    • 排名:千里之外
    • 原创:85篇
    • 转载:5篇
    • 译文:0篇
    • 评论:20条
    文章分类
    最新评论