我正在将排序算法作为个人培训来实现(没有功课!)。我有以下代码(不包括导入等):
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));
编译器抱怨“对重载函数的歧义调用”(VC ++ C2668)。从我的理解来看,这个电话应该不是模棱两可的。同样,给第二个排序函数中的调用一个第一个排序函数的模板参数没有任何作用。
我在这里想念什么?编译器为何将第二个调用视为“模棱两可”?
问题有两个。
首先,sort
是通过ADL找到的,因此您将获得两个重载,并且它们都匹配。通常,std
由于ADL可能引起歧义,因此命名功能与不尝试ADL重载时的功能相同。
现在,仅当从传递namespace std;
迭代器的类型时才发生这种情况,有时迭代器是从此名称空间获取的,但在这种情况下则不会:array
使用原始指针迭代器。查找ADL的触发因素std::sort
是std::function
。
这就引出了下一个问题:std::function
在上述代码中,几乎没有什么收获,而有很多损失。替换为auto
。将低级排序算法传递给可内联的比较对象。
您仍然不想调用它sort
。如果调用它sort
,则需要使用名称空间来限定调用,或(sort)
阻止ADL。
ADL规则是考虑“重载”函数,以及参数命名空间中的函数,参数指向的命名空间,参数指向的命名空间以及参数的模板参数等。这是依赖于参数的查询,或ADL或Koenig查找。这意味着当使用另一个命名空间中的类型时,可能会发生某种类型的命名空间污染(这很可悲),但这也会带来一些不错的魔术效果(例如std :: cout <<“ hello world \ n”;`)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句