Search code examples
c++templatesgeneric-programming

Overloaded template resolution


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);
}

Solution

  • 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.