重载的模板分辨率

Igo*_* R. 4 c++ templates generic-programming

以下代码打印"First".为什么选择第一个模板,而第二个模板似乎更专业,应该是更好的匹配?(我使用MSVC10)

我知道它与const &某个事实相关,即第二个模板接受了它的参数,但仍然无法理解为什么这会使它更糟糕.

#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);
}
Run Code Online (Sandbox Code Playgroud)

Seb*_*edl 13

编译器将第一个模板实例化为

void go(std::map<int, int>& r)
Run Code Online (Sandbox Code Playgroud)

和第二个

void go(const std::map<int, int>& m)
Run Code Online (Sandbox Code Playgroud)

第一个转换序列是身份转换:不需要做任何事情,lvalue参数直接绑定到引用.

第二个转换序列是限定符转换:lvalue参数需要添加const以绑定到引用.

所以第一个是更好的匹配.如果变量in main是开始的const,那么第二个将是更好的匹配,正如你在这里看到的那样,因为这两个模板实例化为同一个东西,然后"更专业化"的概念才起作用.