模板编程:对重载函数

时间:2015-05-24 09:22:04

标签: c++ templates c++11 visual-c++

我正在实施一种排序算法作为个人训练(没有作业!)。 我有以下代码(不包括导入等):

        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;?

1 个答案:

答案 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 ;;`)