The following code prints "First". Why the 1st template is selected, while the the 2nd one seems to be more specialized and should be a better match? (I use MSVC10)
I understand that it's somehow related to the fact that the second template accepts its argument by const &
, but still can't realize why this make it a worse match.
#include <map>
#include <iostream>
template<class Range>
void go(Range &r)
{
std::cout << "First" << std::endl;
}
template<class K, class V>
void go(const std::map<K, V> &m)
{
std::cout << "Second" << std::endl;
}
int main()
{
std::map<int, int> m;
go(m);
}
The compiler instantiates the first template to
void go(std::map<int, int>& r)
and the second to
void go(const std::map<int, int>& m)
The conversion sequence for the first is an identity conversion: nothing needs to be done, the lvalue argument binds directly to the reference.
The conversion sequence for the second is a qualifier conversion: the lvalue argument needs const added to bind to the reference.
So the first is a better match. If the variable in main
was const to begin with, the second would be a better match, as you can see here, because then the two templates instantiate to the same thing and only then does the concept of "more specialized" come into play.