- 论坛徽章:
- 0
|
这段代码在gcc version 4.1.0 20060304 (Red Hat 4.1.0-3)
以及 gcc version 4.1.1 20061011 (Red Hat 4.1.1-30)都编译不过去
// main.cpp
#include <iostream>
using namespace std;
void print(const char *){}
template <typename Type>
Type sum(Type op1, int op2)
{
cout << "Type sum(Type op1, int op2)" << endl;
print("ggggggggg");
print(op1);
return op1;
}
void print(int a){}
int main(int argc, char **argv)
{
sum(8, 10);
return 0;
}
// 实例化点
/***************************
int sum<int>(int, int)
{
.........
}
***************************/
在gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)编译及运行都很好。
对有些人的回答不再理会以免其在这里灌水
编译指令 g++ main.cpp
对于认为 在模板定义中所有用到的函数都要要首先声明的请看
c++primer 第三版 10.9 模板定义中的名字解析
节的解释。
我发现了这个问题,就从c++primer上抄了这段代码,结果真的不行。
问题已解决,感谢大家的回答,特别是 whyglinux 的耐心的解释 如下:
我在上面回答 xiaoligang 提出的这个问题的时候,其实还没有真正了解问题的实质,所以可忽略我上面的回答,请参见下面的回答:
对于依赖模板参数的函数的解析问题,在原来 C++ 98 标准的基础上根据下面的一个缺陷报告进行了一些修正。
197. Issues with two-stage lookup of dependent names
也就是说,在《C++ Primer 3》中的有关叙述对于模板参数是基本类型的情况已经过时了。
当传入模板函数的模板参数是一个基本类型(fundamental type)的时候,由于基本类型不具有关联名字空间和类域(associated namespaces and classes),所以没有额外的空间进行名字查找,只进行默认的名字查找(其搜索范围是在名字被使用之前),因此要求在使用之前要有函数的声明存在。
如果模板参数是非基本类型,比如是一个类类型,则除了默认的查找范围外,还可以查找这个类的类域以及这个类所在的名字空间等关联空间。所以,函数的声明无论是在类定义之前还是之后都处于名字搜索空间内都可以被找到。
根据上面的分析可知:楼主的程序是一个不正确的程序,因为 print(int) 将永远也不会被找到,当然也不会被调用。唯一能找到的函数声明是在使用 print 之前出现的 print(const char *)。显然,当函数模板参数类型和 const char * 不一致的时候一般会导致编译错误。
新版的 GCC 编译器遵循了这一新的 C++ 标准的规定,而旧版的没有,也就出现了两种不同的编译结果。
[ 本帖最后由 xiaoligang 于 2007-1-30 09:42 编辑 ] |
|