C++primer练习16.64

今天看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;
}

猜你喜欢

转载自blog.csdn.net/zhc_futrue/article/details/79317522