繁体   English   中英

模板编程:对重载函数的歧义调用

[英]template programming: ambiguous call to overloaded function

我正在将排序算法作为个人培训来实现(无需做作业!)。 我有以下代码(不包括导入等):

        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)。 从我的理解来看,这个电话应该不会模棱两可。 同样,给第二个排序函数中的调用一个第一个排序函数的模板参数没有任何作用。

我在这里想念什么? 为何编译器将第二个调用视为“模棱两可”?

问题有两个。

首先,通过ADL查找sort ,因此您将获得两个重载,并且它们都匹配。 通常,由于ADL可能引起歧义,因此当您不尝试ADL重载时,命名功能与std函数相同。

现在,仅当从namespace std;传递类型时才会发生这种情况namespace std; 有时迭代器来自此名称空间,但在这种情况下不是: array使用原始指针迭代器。 ADL查找std::sort的触发器是std::function

这就引出了下一个问题:上面代码中的std::function带来的收获很少,而损失的很多。 将其替换为auto 将低级排序算法传递给可内联的比较对象。

您仍然不希望将其称为sort 如果调用它进行sort ,则需要使用名称空间来限定调用,或(sort)以阻止ADL。

ADL规则是考虑“重载”函数,以及参数名称空间中的功能,参数指向的名称空间,参数指向的名称空间以及参数的模板参数等。 这是基于参数的查找或ADL或Koenig查找。 这意味着当使用另一个命名空间中的类型时,可能会发生某种类型的命名空间污染(这很可悲),但是这也会使一些不错的事情发生(例如std :: cout <<“ hello world \\ n”;`)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM