LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 894|回复: 10

写template的时候发现的问题

[复制链接]
发表于 2006-1-9 17:15:34 | 显示全部楼层 |阅读模式
test.cpp:=================================
#include <iostream>

#include "test_math.h"

using namespace std;

int main(void)
{
        cout << getmax<int>(12, 21) << endl;

        return 0;
}

test_math.h:==============================
#ifndef TEST_MATH_H_
#define TEST_MATH_H_

template <class T> T getmax(T a, T b);

#endif

test_math.cpp:=============================
#include "test_math.h"

template <class T> T getmax(T a, T b)
{
        return (a > b) ? a : b;
}

编译:
g++ -otest test.cpp test_math.cpp
test.cpp: undefined reference to 'int getmax<int>(int, int)'

但是如果把它们都放在同一个文件就不会发生这样的事。
有人知道为什么吗?
发表于 2006-1-9 20:49:55 | 显示全部楼层
这都是编译器的错,因为g++还不支持export关键字
回复 支持 反对

使用道具 举报

发表于 2006-1-9 23:42:19 | 显示全部楼层
现在的g++编译器无法支持模板的分离编译,因为在单独编译模板的时候对于参数类型编译器不知道对哪个类型实例化。因此在和别的object连接的时候会出现undefined reference错误,因为编译器没有生成针对该类型的实例化。

目前只能把模板函数、模板类的定义写在头文件里。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-1-10 00:33:08 | 显示全部楼层
Oh,原来是这样的!受教了!
回复 支持 反对

使用道具 举报

发表于 2006-1-10 12:05:22 | 显示全部楼层
Post by manphiz
目前只能把模板函数、模板类的定义写在头文件里。


not exactly,have a look at the following example:

test.h

  1. #ifndef __H__
  2. #define __H__


  3. template <typename T>
  4. void f(T t);

  5. #endif
复制代码


func.cc

  1. #include <iostream>
  2. #include "test.h"

  3. template <typename T>
  4. void f(T t)
  5. {
  6.         std::cout<<t<<std::endl;
  7. }

  8. template void f<int>(int);
复制代码


test.cc

  1. #include "test.h"

  2. int main()
  3. {
  4.         f(2);
  5.         return 0;
  6. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-1-10 17:38:21 | 显示全部楼层
Post by rickxbx
not exactly,have a look at the following example:

test.h

  1. #ifndef __H__
  2. #define __H__


  3. template <typename T>
  4. void f(T t);

  5. #endif
复制代码


func.cc

  1. #include <iostream>
  2. #include "test.h"

  3. template <typename T>
  4. void f(T t)
  5. {
  6.         std::cout<<t<<std::endl;
  7. }

  8. [color="Red"][size=7]template void f<int>(int);[/size][/color]
复制代码


test.cc

  1. #include "test.h"

  2. int main()
  3. {
  4.         f(2);
  5.         return 0;
  6. }
复制代码


这样用法就没必要template了吧
回复 支持 反对

使用道具 举报

发表于 2006-1-10 17:56:16 | 显示全部楼层
to gulfstream:
1. 那只是说明一个道理(模板定义并不一定要放在头文件)
2. 如果是这样呢:

test.h
  1. #ifndef __H__
  2. #define __H__
  3. template <typename T>
  4. void f(T t);
  5. #endif
复制代码

func.cc
  1. #include <iostream>
  2. #include "test.h"
  3. template <typename T>
  4. void f(T t)
  5. {
  6.         std::cout<<t<<std::endl;
  7. }
  8. template void f<int>(int);
  9. template void f<char>(char);
  10. template void f<std::string>(std::string);
复制代码

test.cc
  1. #include "test.h"
  2. #include <string>
  3. int main()
  4. {
  5.         f(2);
  6.         f('a');
  7.         std::string str("Hello");
  8.         f(str);
  9.         return 0;
  10. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-1-10 18:01:15 | 显示全部楼层
这样的用法失去了模版的灵活性

Post by rickxbx
to gulfstream:
1. 那只是说明一个道理(模板定义并不一定要放在头文件)
2. 如果是这样呢:

test.h

  1. #ifndef __H__
  2. #define __H__


  3. template <typename T>
  4. void f(T t);

  5. #endif
复制代码


func.cc

  1. #include <iostream>
  2. #include "test.h"

  3. template <typename T>
  4. void f(T t)
  5. {
  6.         std::cout<<t<<std::endl;
  7. }

  8. template void f<int>(int);
  9. template void f<char>(char);
  10. template void f<std::string>(std::string);
复制代码


test.cc

  1. #include "test.h"
  2. #include <string>

  3. int main()
  4. {
  5.         f(2);
  6.         f('a');
  7.         std::string str("Hello");
  8.         f(str);
  9.         return 0;
  10. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-1-10 18:29:25 | 显示全部楼层
呵呵,楼上说的甚是
回复 支持 反对

使用道具 举报

发表于 2006-1-10 19:25:53 | 显示全部楼层
呵呵,版版将模板显式实例化。不过这样就没法泛型编程了
(吹毛求疵一下,版版的第二个func.cc要`#include <string>'才是 ;) )

等待下一代C++0x标准来解决这个问题吧!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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