模板化函数名称查找难题(ADL)

时间:2013-01-21 02:44:34

标签: c++ templates mismatch argument-dependent-lookup name-lookup

鉴于以下代码,为什么调用Generic函数而不是更具体的基于SomeClass的函数呢?

template <typename T>
class SomeClass
{
};

template <typename T>
void foo(T)
{
   std::cout << "foo() Generic - Undesired function\n";
}

template <typename T>
void foo(const SomeClass<T>*)
{
   std::cout << "foo() SomeClass<T> - Desired function\n";
}


int main()
{
   SomeClass<char>* sc = new SomeClass<char>();
   foo(sc);
   return 0;
}

注意:如果我要从“void foo(const SomeClass<T>*)”定义中删除const,则会调用所需的函数。虽然它没有任何影响,但我也尝试重新排列foo。如果可能的话,请调用描述此特定ADL场景的标准中的相关区域。

使用const:http://ideone.com/DIchLl

没有const:http://ideone.com/Iam4LV

使用const(1st):http://ideone.com/W6PoJw

2 个答案:

答案 0 :(得分:2)

因为没有const的人需要较少的转化次数。当编译器选择重载时,它首先查找完全匹配的重载,然后按特定顺序进行一系列转换,找到的第一个是使用的。

在此示例中,scSomeClass<char>*&。编译器首先尝试完全匹配,并且由于没有,它会尝试删除&。因为它找到了一个,它会退出查找,并且不会添加允许它看到另一个的const

答案 1 :(得分:2)

foo(T)T = SomeClass<T>*的参数完全匹配。

foo(const SomeClass<T>*)需要资格转换(添加const限定符)。

完全匹配优于需要任何类型转化的匹配,即使它只是资格转换。