我正在实施一种排序算法作为个人训练(没有作业!)。 我有以下代码(不包括导入等):
template<class RandomIt, class Compare>
void sort(RandomIt first, RandomIt last, Compare comp)
{
/* actual sorting code is here */
}
template<class RandomIt>
void sort(RandomIt first, RandomIt last)
{
std::function<bool(decltype(*first), decltype(*last))> comp = [](decltype(*first) a, decltype(*last) b)
{
return a < b;
};
sort (first, last, comp);
}
尝试使用测试数组
调用此代码 auto test_array_1 = std::make_unique <std::array < uint64_t,SORTING_TEST_LENGTH >> ();
std::copy(std::cbegin(*template_array), std::cend(*template_array), std::begin(*test_array_1));
sort(std::begin(*test_array_1), std::end(*test_array_1));
编译器抱怨&#34;模糊调用重载函数&#34; (VC ++ C2668)。根据我的理解,这个电话不应该含糊不清。同样在第二个排序函数中给出调用,第一个排序函数的模板参数没有任何效果。
我在这里缺少什么?为什么编译器会考虑第二个调用&#34;不明确的&#34;?
答案 0 :(得分:6)
问题有两个。
首先,通过ADL找到sort
,因此您得到两个重载,它们都匹配。一般来说,当你没有尝试ADL重载时,命名函数与std
函数的作用相同,因为ADL引起的模糊性可能会发生。
现在,只有从namespace std;
传递类型时才会发生这种情况。有时迭代器来自此命名空间,但在这种情况下不是:array
使用原始指针迭代器。 ADL查找std::sort
的触发器是std::function
。
这让我想到了下一个问题:在上面的代码中std::function
只能获得很少的东西,而且很多东西都会丢失。将其替换为auto
。将低级排序算法传递给可内联的比较对象。
您仍然不想将其称为sort
。如果您将其称为sort
,则需要使用命名空间限定调用,或(sort)
来阻止ADL。
ADL规则是&#34;通常&#34;函数和参数名称空间中的函数,以及参数的名称空间和参数的模板参数等,都被认为是重载解析。这是Argument Dependent Lookup,或ADL,或Koenig查找。这意味着当使用来自另一个命名空间的类型时,可能会发生类型的命名空间污染(这很难过),但它也会产生一些不错的魔法(比如std :: cout&lt;&lt;&#34; hello world \ n&#34 ;;`)