【问题标题】:template programming: ambiguous call to overloaded function模板编程:对重载函数的模糊调用
【发布时间】:2015-05-24 09:22:03
【问题描述】:

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

        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)。根据我的理解,这个电话不应该是模棱两可的。同样在第二个排序函数中调用第一个排序函数的模板参数没有任何效果。

我在这里缺少什么?为什么编译器会认为第二次调用“模棱两可”?

【问题讨论】:

  • 尝试给出整个错误......我们的任何帮助都只是在黑暗中拍摄。
  • 如果你有一个using namespace foostdfoo 的明显罪魁祸首),它可能已经有一个sort
  • 有趣的是,我的代码中没有using namespace std(我讨厌命名空间污染)。
  • 欢迎来到ADL,这里可以找到std::sort,因为std::begin产生的迭代器在std命名空间,拉入std::sort
  • Argument Dependent Lookup - 基本上,对于不合格的函数调用,查看参数的命名空间、它们的模板参数、它们的基类,以及它们的狗曾曾祖母的命名空间。跨度>

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


【解决方案1】:

问题有两个方面。

首先,sort 是通过 ADL 找到的,所以你得到两个重载,它们都匹配。一般来说,当您不尝试 ADL 重载时,将函数命名为与 std 函数相同的名称是令人担忧的,因为可能会导致 ADL 引起歧义。

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

这让我想到了下一个问题:在上面的代码中,std::function 获得的很少,损失的很多。将其替换为auto。向低级排序算法传递一个可内联的比较对象。

你还是不想叫它sort。如果你称它为sort,你需要使用命名空间来限定调用,或者(sort) 来阻止ADL。

ADL 规则是“常规”函数、参数命名空间中的函数、参数指向的命名空间以及参数的模板参数等都被考虑用于重载解析。这是参数相关查找,或 ADL,或 Koenig 查找。这意味着当使用来自另一个命名空间的类型时,可能会发生某种命名空间污染(这很可悲),但它也会产生一些美妙的魔法(比如 std::cout

【讨论】:

  • 很好的解释。只是想指出名称sort 的选择是故意的,因为我想坚持标准库接口。我知道标准库的实现会更好,但如前所述,整个项目是一个训练练习,让我在 C++ 的某些方面变得更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2011-12-12
  • 2014-09-05
  • 2016-03-26
  • 1970-01-01
相关资源
最近更新 更多