分类: C/C++
2008-05-11 17:33:42
template <>
int FOO
{return 12;}
const char* b;
cout << FOO(1, b) << endl;
结果是啥?
template
int FOO(T, const U*)
{return 1;}
template <>
int FOO
{return 12;}
const char* b;
cout << FOO(1, &b) << endl;
结果是啥?
template
int FOO(T, U)
{return 1;}
template <>
int FOO
{return 12;}
const char* b;
cout << FOO(1, b) << endl;
又是啥
/***********************************************************
示例1:
***********************************************************/
/*baihacker , devc++*/
#include
using namespace std;
/*
模板0:
*/
template
int FOO(T, const U*)
{return 1;}
/*
模板1:
用int, const char 实例化模板,得到
FOO (int, const char*)
*/
template <>
int FOO
{return 2;}
/*
模板2:
参数是int , const char*
推测出是用int, char 实例化模板
*/
template <>
int FOO(int, const char*)
{return 3;}
/*
参数是int, char*
无法推测出是实例化哪个模板,error
template <>
int FOO(int, char*)
{return 3;}
*/
/*普通函数,优先级最高*/
int FOO(int, const char*)
{return 4;}
int main()
{
const char* b;
/*
参数是int , const char*
推测出是用int, char 实例化模板
*/
cout << FOO(1, b) << endl;
/*
结果为4,因为普通函数最高
去掉这个普通函数,结果为3,根据参数推测到使用FOO template with T = int, U = char
只保留模板0,1,结果为1
根据参数推测到使用 FOO template with T = int, U = char,虽然
第二个函数的参数是int, const char* 但是使用的是 FOO template with T = int, U = const char
故不调用第二个函数
由于const const char* 还是const char*,所以对于这个参数,并强制使用模板
FOO template with T = int, U = const char 是没有错误的
问题:什么时候才可能调用第二个模板 ?
如果把<>内的const去掉,则
template <>
int FOO
{return 2;}
template <>
int FOO(int, const char*)
{return 3;}
等价,同时出现一个重复定义的错误
*/
cin.get();
return 0;
}
/***********************************************************
示例2:
***********************************************************/
/*baihacker , devc++*/
#include
using namespace std;
/*
模板0:
*/
template
int FOO(T, const U*)
{return 0;}
/*
模板1:
*/
template <>
int FOO
{return 1;}
/*
模板2:
*/
template
int FOO(T, U*)
{return 2;}
/*
模板3:
*/
template <>
int FOO(int, char*)
{return 3;}
int main()
{
const char* b;
cout << FOO(1, &b) << endl;
/*推测出来使用模板2, 这个 匹配度最高
去掉模板2,3后调用模板1*/
cin.get();
return 0;
}
结论:
template<>
int FOO(...);
是根据参数选择模板全特化
template<>
int FOO<...>(...);
全特化模板,并根据参数匹配模板检查
调用的时候根据参数确定T,U,然后再调用特别注意示例1中
FOO template with T = int, U = const char
FOO template with T = int, U = char
在参数上表现相同
但是是不同的模板!
补充一点:
特化最好使用
template<>
int FOO<...>(...);
这样使得编译器不太累,让你看起来也不累
否则有时连你都不知道推测出来使用的是什么模板,结果特化无效
template <>
int FOO
{return 123;}
template <>
int FOO(int, const char* const *)
{return 123;}
上面两个等价,但是用<>可以更好地指明模板中T和U是什么
/***********************************************************
示例3:
***********************************************************/
/*baihacker , devc++*/
#include
using namespace std;
/*
模板0:
*/
template
int FOO(T, U)
{return 1;}
/*
模板1:
FOO template with T = const int, U = const int
*/
template <>
int FOO
{return 2;}
/*
模板2:
FOO template with T = int, U = int
*/
template <>
int FOO
{return 3;}
int main()
{
const int a = 1;
const char* b;
cout << typeid(b).name() << endl;
cout << FOO(a, a) << endl;//参数本身的类型是int故 FOO template with T = int, U = int
cout << FOO(1, 1) << endl;//参数本身的类型是int故 FOO template with T = int, U = int
cin.get();
return 0;
}
/*
const 是类型限定符(另一个是volatile)
a的类型是int
1的类型也是int
const char* a 的 类型是 char const * (和const char * 等价)
char * const a的 类型是 char*
所以一个const作用在一个普通类型,const并不作为类型的一部分
只有const来修饰指针指向的内容的时候 才作为类型的一部分
const修饰的参数的可以接受非const的变量
char const* const *为函数参数类型
char const * b :&b的类型是 char const * * 指向一个指向常字符串的指针
char const* const *的类型是一个指向常字符串的常量指针
所以 char const* const *能接受&b
在这里如果直接使用模板1
那么结果不是你所期望的
所以最好使用
模板1:
FOO template with T = int, U = int
template <>
int FOO(const int, const int)
{return 2;}
让编译器推导使用哪个模板
和前面的文章分析结果相反
建议:
在简单类型,含const时使用自动推导
在有指针的时候,最好直接指明
*/
/*示例4 来自csdn的问题*/
/*devc++*/
#include
#include
using namespace std;
typedef char* PCHAR ;
void TestFunc(const PCHAR & pConstRef)
{
PCHAR ptr1 = pConstRef;
const char *ptr2 = pConstRef;
cout <<"pConstRef 's Type:" << typeid(pConstRef).name() << endl;
cout <<"ptr1 's Type: " << typeid(ptr1).name() << endl;
cout <<"ptr2 's Type: " << typeid(ptr2).name() << endl;
//*ptr1 = 'a';
}
template
void TestFunc2(const T & pConstRef)
{
T var1 = pConstRef;
const T var2 = pConstRef;
cout <<"pConstRef 's Type:" << typeid(pConstRef).name() << endl;
cout <<"var1 's Type: " << typeid(var1).name() << endl;
cout <<"var2 's Type: " << typeid(var2).name() << endl;
}
int main(int argc, char *argv[])
{
char pBuf[100] = "suntao";
char* pNonConst = pBuf;
TestFunc (pNonConst);
TestFunc2 (pNonConst);
cin.get();
return EXIT_SUCCESS;
}
/*
结果是TestFunc2内的var2类型不同
先分析一下:
TestFunc:
const PCHAR & pConstRef
去掉pContsRef,去掉&得到 pConstRef的类型是 const PCHAR
const规则:const PCHAR = PCHAR const
注意到 typedef char* PCHAR ;
const char* = char* const
所以const PCHAR & pConstRef只是保证pConstRef不变
ptr1, ptr2的类型显然
对于 TestFunc2所有的类型显然
typedef char* PCHAR ;
const PCHAR var1;
const char * var2;
=>var1 和 var2是不同的类型
所以在使用模版的时候要注意!
*/