今天看C++primer时在做这个练习题的时候遇到了问题,下面时我最开始写的代码:
// 通用的模板
template<typename T1,typename T2>
int Cal(const vector<T1>& t1, const T2& t2)
{
cout << "T" << endl; //观察调用的是哪一个函数
int cnt = 0;
for (auto i : t1)
{
if (i == t2)
cnt++;
}
return cnt;
}
// 特例化的模板
template<>
int Cal(const vector<const char*> &t1, const char* const& t2)
{
cout << "const char*" << endl; // 观察调用的是那一个函数
int cnt = 0;
for (auto i : t1)
{
if (!strcmp(i, t2))
{
++cnt;
}
}
return cnt;
}
int main()
{
const char a[] = "a", b[] = "b", c[] = "c", d[] = "d";
vector<const char*> cvec = { a,b,c,d };
cout << Cal(cvec, a) << endl;
return 0;
}
本以为运行Cal(cvec,a)时调用的是特例化的那个版本,但是实际上却是调用的通用的那个模板
找了下原因,原来是因为调用Cal(cvec,a)的时候传递给模板是数组类型(因为函数形参是引用的缘故,可在通用的函数模板中加一句 cout << typeid(t2).name() << endl; 查看 t2 的类型),所以调用的是通用的那个版本。正确的做法是将引用去掉,这样调用Cal(cvec,a)的时候传递给模板的就是指针类型了(隐式类型转换),这是通用的模板和特例化的模板都是精确匹配,但是由于特例化的原因,将会调用特例化的那个版本。
正确的代码如下:
// 通用的模板
template<typename T1,typename T2>
int Cal(const vector<T1>& t1, const T2 t2)
{
cout << typeid(T2).name() << endl;
cout << "T" << endl; //观察调用的是哪一个函数
int cnt = 0;
for (auto i : t1)
{
if (i == t2)
cnt++;
}
return cnt;
}
// 特例化的模板
template<>
int Cal(const vector<const char*> &t1, const char* const t2)
{
cout << "const char*" << endl; // 观察调用的是那一个函数
int cnt = 0;
for (auto i : t1)
{
if (!strcmp(i, t2))
{
++cnt;
}
}
return cnt;
}
int main()
{
const char a[] = "a", b[] = "b", c[] = "c", d[] = "d";
vector<const char*> cvec = { a,b,c,d };
cout << Cal(cvec, a) << endl;
return 0;
}