游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2650|回复: 5

c++模板编译问题

[复制链接]

1

主题

14

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2009-6-15 21:44:00 | 显示全部楼层 |阅读模式

我在工程里添加了三个文件

1.test.h 内容如下:

template<class T>

class CTest
{
public:
        void fun(T);
};


2.test.cpp 内容如下

#include "test.h"

template<class T>
void CTest<T>::fun(T){};


3.main.cpp 内容如下:
#include "test.h"

int main(void)
{

        CTest<int> test;
        test.fun(1);
        return 0;
}

生成代码时显示:

正在编译...
main.cpp
正在生成代码...
正在编译...
test.cpp
正在生成代码...
正在编译资源清单...
正在链接...
main.obj : error LNK2019: 无法解析的外部符号 "public: void __thiscall CTest<int>::fun(int)" (?fun@?$CTest@H@@QAEXH@Z),该符号在函数 _main 中被引用


请高手指教.

注:如果把类成员的实现放在头文件里,可以编译通过.


0

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2009-6-16 03:24:00 | 显示全部楼层

Re: c++模板编译问题

模板要具现化才能用,放在cpp里也可以 就要手动具现化一下.

2.test.cpp 内容如下

#include "test.h"

template<class T>
void CTest<T>::fun(T){};

tymplate void CTest<int>::fun(int)();
这句就是帮你生成一个int参数的函数定义式.
void CTest::fun(int i){}
好像这样就不是内联了...

3

主题

32

帖子

36

积分

注册会员

Rank: 2

积分
36
发表于 2009-6-16 15:58:00 | 显示全部楼层

Re:c++模板编译问题

模板要具现化才能用,也就是在main.cpp中用到CTest模板,这里里要完整的模板定义才能根据模板参数来生成相应类型的函数,这里出错是因为在main.cpp中看不到fun的实现,编译器没有办法生成相应的函数

因为模板的这种特性,一般模板库习惯上全都在.h中编写所有代码,像STL

19

主题

52

帖子

52

积分

注册会员

Rank: 2

积分
52
发表于 2009-6-16 16:03:00 | 显示全部楼层

Re:c++模板编译问题

2,3l说的不清不楚的
简单讲就是
类模板的代码不能放CPP文件里编译
所有代码都要放在头文件

0

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2009-6-16 20:46:00 | 显示全部楼层

Re: Re:c++模板编译问题

keeponshoot: Re:c++模板编译问题

2,3l说的不清不楚的
简单讲就是
类模板的代码不能放CPP文件里编译
所有代码都要放在头文件

为什么不能放在cpp里? 我放cpp里一样可以啊,但就不内联而已.

.test.cpp 内容如下
#include "test.h"
template<class T>
void CTest<T>::fun(T){};
//具现化模板
tymplate void CTest<int>::fun(int)();

0

主题

398

帖子

577

积分

高级会员

Rank: 4

积分
577
发表于 2009-6-17 11:37:00 | 显示全部楼层

Re:c++模板编译问题

从两个角度说下:1、模板简单的理解就是一种按照数据类型的套用格式,所以模板函数的实现放在CPP中也不会在编译阶段生成目标代码。在连接阶段找不到目标代码当然就会连接出错了。一般情况下都是放在头文件中,这样在编译引用此头文件并且指明了具体数据类型的CPP文件时会按照模板中的格式替换数据类型编译,依此生成目标代码。2、模板声明之后并不会编译成为目标代码,需要你具体制定套用哪种数据类型才可以,如果只指定为int,则在编译时把所有“T”的位置替换为int然后编译,如果你指定了float,则也会进行相应的替换。简单的说就是编译器自动帮你生成了针对int和float的重载函数。当然你也可以指定一个class,但是前提是这个class必须支持你在这个模板函数中所使用的符号,例如
template<typename T>
T a,b,c;
a = b + c;
如果T使用了class,则这个class必须重载“+”和“=”操作符。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-19 23:24

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表