The following short code fragment no longer compiles with gcc 4.1. I've no clue if this a regression or mandated by the standard. #include <algorithm> #include <string> #include <vector> int size(char x) { return (int) sizeof(x); } int size(int x) { return (int) sizeof(x); } int size(const std::string &x) { return (int) x.size() + (int) sizeof(int); } template <class T> int size(const std::vector<T> &x) { int result = (int) sizeof(int); typename std::vector<T>::const_iterator iter; for (iter = x.begin() ; iter != x.end() ; iter++) result += size(*iter); return result; } template <class T, class TT> int size(const std::pair<T,TT> &x) { return size(x.first) + size(x.second); } int foo() { std::vector<std::pair <std::string, std::string> > pvec; return size(pvec); } Sorry to not reduce a stand-alone testcase without headers. The STL isn't important. The issue is that the list of candidates for "size(std::pair<...>)" doesn't include the templates, only the functions, when instantiating "size(std::vector<...>). On IRC they thought this looked reasonable enough to file a PR. This works fine in 4.0.2 and 3.4.x and many other C++ compilers.
*** Bug 26080 has been marked as a duplicate of this bug. ***
The issue here (in the source) is that the overloaded of " result += size(*iter);" is only the size functions above that call so it does not see the template below that call which is the function you would like to call. This is how standard C++ works (with the correction from DR 197). This is a dup of bug 2922 which was fixed by rejecting invalid code and fixing wrong code for 4.1. The way to fix the code is to add a forward to the template function. So the following code is the legal corrected code: #include <algorithm> #include <string> #include <vector> int size(char x) { return (int) sizeof(x); } int size(int x) { return (int) sizeof(x); } int size(const std::string &x) { return (int) x.size() + (int) sizeof(int); } template <class T, class TT> int size(const std::pair<T,TT> &x); template <class T> int size(const std::vector<T> &x) { int result = (int) sizeof(int); typename std::vector<T>::const_iterator iter; for (iter = x.begin() ; iter != x.end() ; iter++) result += size(*iter); return result; } template <class T, class TT> int size(const std::pair<T,TT> &x) { return size(x.first) + size(x.second); } int foo() { std::vector<std::pair <std::string, std::string> > pvec; return size(pvec); } -------- The missing of the first template in the diangostic is just a diagnostic bug which was reported somewhere else too, PR 16057. *** This bug has been marked as a duplicate of 2922 *** *** This bug has been marked as a duplicate of 2922 ***