模板除了声明类型外,还可以使用一个常量来区分模板的类型,例如
template <int a>
void f1() {cout<<a;}
int main()
{
fa<3> ();
return 0;
}
但是,当常量模板要求是一个地址的时候,比如
template <const char *const s>
void f1() {cout<<s;}
int main()
{
const char*const p1="asdfg";
f1<p1>();//非法1
f1<"asdf">();//非法2
return 0;
}
似乎能想到表示常量的方法都用上了,难道真的没有办法根据一个字符串来绑定一个模板实例了?
问题还是处在常量这个概念上。
对于式子1:const char*const p1="asdfg";这个看起来是常量,实际上编译器并不认可。编译器的接口是const char*const s类型,但是就算是这样
也无法保证s的值能不被改变。例如
char *p=new char[5];
const char*const s=p;
实际上s指向的地址随时可能被p给delete掉。也就是说,这样根本不是常量。
再看式子2:f1<"asdf">();//非法2
咋一看"asdf"一定是常量了,地址就是&"asdf"[0],但是这样还是不行,因为他没有上下文的关联。但是实际上我还是觉得程序已经给这个地址命名了,他就叫"asdf",
这就是变量名,不清楚为什么在上下文无法使用。
最后,试了下
char s[5]="asdf";
f1<s>();通过了,这个也是合情合理的,本来数组名就是首地址,也就是const char*类型的。
最后试了下switch语句,更加印证了这个道理:
const int a=3;
int k=3;
const int* const p=&a;
switch (k)
{
case a:*******//合法,a是常量
case (*p):******//非法,因为程序无法保证*p的值不会被修改。只能保证在p或者其他从p赋值地址的指针不修改*p的内容
}