Weird C++ template question

Revision en1, by tribute_to_Ukraine_2022, 2018-01-29 01:23:50

I tried to define two template functions outputing pairs and vectors of any type. If it is overloaded operator it works fine, but for standard functions lookup fails to find function defined for pair if it is declared after called. Does anybody know why?

# include <bits/stdc++.h>
using namespace std;
int Hash(int x) {
	return x;
}
template <typename T> int Hash(vector<T> x) {
	int ans = 0;
	for (auto c : x)
		ans = 2 * ans + Hash(c);//Fails if c is a pair: no matching function for call to ‘Hash(std::pair<int, int>&)
	return ans;
}
template <typename T, typename C> auto Hash(pair <T, C> x) -> int {
	return Hash(x.first) + Hash(x.second) * 14;
}
template <typename T>
ostream &operator<<(ostream &os, vector <T> x)
{
	os << "{";
	int cou = 0;
	for (auto c : x) {
		if (cou++) os << ", ";
		os << c;//Works even if c is a pair despite calling operator declared late
	}
	return os << "}";
}
template <typename T, typename C> ostream & operator<< (ostream &os, pair<T, C> x) {
	return os << "<" << x.first << ", " << x.second << ">"; 
}
ostream & Output(ostream &os, const char * x) {
	return os << x;
}
ostream & Output(ostream &os, int x) {
	return os << x;
}
template <typename T>
ostream &Output(ostream &os, vector <T> x)
{
	Output(os, "{");
	int cou = 0;
	for (auto c : x) {
		if (cou++) Output(os,  ", ");
		Output(os, c);//Fails if c is a pair: no matching function for call to ‘Output(std::ostream&, std::pair<int, int>&)
	}
	return Output(os, "}");
}
template <typename T, typename C> ostream & Output (ostream &os, pair<T, C> x) {
	return Output(Output(Output(Output(Output(os, "<"), x.first), ", "), x.second), ">"); 
}
int main() {
	vector <pair <int, int> > x;
	x.emplace_back(13, 10);
	x.emplace_back(1, 16);
	cout << x << endl;//Compiles and outputs {<13, 10>, <1, 16>}
	cout << Hash(x) << endl;//no matching function for call to ‘Hash(std::pair<int, int>&)    ans = 2 * ans + Hash(c);
	Output(cout, x);//no matching function for call to ‘Output(std::ostream&, std::pair<int, int>&)   Output(os, c);
}

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en1 English tribute_to_Ukraine_2022 2018-01-29 01:23:50 2128 Initial revision (published)