|
发表于 2008-1-6 23:39:59
|
显示全部楼层
Post by hong8292;1803613
引用:
作者:manphiz
2、错误的模板实例化点:
代码:
template<class T> void foo(T a);
template<> void foo<int>(int a);
void bar()
{
foo('a');
}
template<> void foo<char>(char a);
int main()
{
bar(); // foo()应该调用foo<int>,实际调用foo<char>
}
// ...
不好意思,我认为你这个例子自身就有问题。
首先,特化template<> void foo<char>(char a)申明在调用之后,而函数bar()调用在之前,而编译器会尝试在bar()调用foo时用<char>实例化template<class T> void foo(T a),所以编译器会报错:该特化申明点错误。所以我认为上面的代码不能通过编译,无论是vc2005或者g++都是这个结果。
尝试稍作改动的下面的例子:
template<class T> void foo(T a)
{
std::cout<<"template<T>: foo";
std::cout<<"<"
<<typeid(T).name()
<<">"
<<std::endl;
}
template<> void foo<int>(int a)
{
std::cout<<"template<>: "
<<"foo<int>"<<std::endl;
}
void bar()
{
foo('a');
}
int main()
{
bar();
}
如果按照你说的现在没有了template<> void foo<char>(char a), 自然应该调用template<> void foo<int>(int a)了,而实际上编译器还是用<char>实例化基础模版得到
template void foo<char>(char), 并调用之。模板实参的推演是精确匹配的过程,而'a'默认是char型的。
这是在下的拙见,不对之处请指出。
确实,那个例子是错误的,当时没想清楚。多谢指正!
这个例子比较能说明问题(来自 msdn: http://msdn2.microsoft.com/en-us/library/w98s4hs8(VS.80).aspx):- #include <stdio.h>
- namespace N {
- void f(int) { printf("f(int)\n");}
- }
- void g() {
- N::f('a'); // VC++: 应该调用 f(int),实际调用 f(char) 。 g++ 的行为是正确的。
- }
- namespace N {
- void f(char) { printf("f(char)\n");}
- }
- int main() {
- g();
- }
复制代码 |
|