Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板编程:对重载函数的不明确调用_C++_Templates_C++11_Visual C++ - Fatal编程技术网

C++ 模板编程:对重载函数的不明确调用

C++ 模板编程:对重载函数的不明确调用,c++,templates,c++11,visual-c++,C++,Templates,C++11,Visual C++,我正在实施一个排序算法作为个人培训(没有作业!)。 我有以下代码(不包括进口等): 模板 无效排序(RandomIt first、RandomIt last、comp比较) { /*实际的排序代码在这里*/ } 模板 无效排序(先随机,后随机) { 函数comp=[](decltype(*first)a,decltype(*last)b) { 返回a(); std::copy(std::cbegin(*模板数组)、std::cend(*模板数组)、std::begin(*测试数组1)); 排序(

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

模板
无效排序(RandomIt first、RandomIt last、comp比较)
{
/*实际的排序代码在这里*/
}
模板
无效排序(先随机,后随机)
{
函数comp=[](decltype(*first)a,decltype(*last)b)
{
返回a
正在尝试使用测试数组调用此代码

    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));
auto-test_-array_1=std::make_-unique>();
std::copy(std::cbegin(*模板数组)、std::cend(*模板数组)、std::begin(*测试数组1));
排序(std::begin(*test_array_1),std::end(*test_array_1));
编译器抱怨“对重载函数的调用不明确”(VC++C2668)。根据我的理解,这个电话不应该含糊不清。在第二个排序函数中调用第一个排序函数的模板参数也没有任何效果


我错过了什么?编译器为什么会考虑第二个调用“暧昧”?

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

现在,这只发生在从
namespace std
有时迭代器来自此命名空间,但在本例中不是:
array
使用原始指针迭代器。ADL查找的触发器是
std::sort
函数

这就引出了下一个问题:在上面的代码中,通过
std::function
,可以获得的东西很少,但会损失很多。将其替换为
auto
。将低级排序算法传递给可内联比较对象

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


ADL规则是,对于重载解析,考虑“常用”函数、参数名称空间中的函数、参数指向的名称空间以及参数的模板参数等。这是依赖于参数的查找,或ADL,或Koenig查找。这意味着当使用来自另一个名称空间的类型时,可能会发生某种类型的名称空间污染(这很糟糕),但它也会产生一些奇妙的效果(比如std::cout问题是双重的

首先,
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尝试给出整个错误…我们方面的任何帮助都只是在黑暗中射击。如果你有一个
使用名称空间foo
std
foo
的明显罪魁祸首),这可能会发生它已经有了一个
排序
。有趣的是,我的代码中没有
使用名称空间std
(我讨厌名称空间污染)欢迎来到ADL,在那里可以找到
std::sort
,因为
std::begin
生成的迭代器位于
std
命名空间中,拉入
std::sort
。依赖于参数的查找-基本上,对于非限定函数调用,查找参数的命名空间、它们的模板参数、它们的基类,还有他们的狗曾曾祖母的名字空间。试着给出整个错误……我们的任何帮助都是无中生有的。如果你有一个
使用名字空间foo
std
foo
的明显罪魁祸首),这可能会发生它已经有了一个
排序
。有趣的是,我的代码中没有
使用名称空间std
(我讨厌名称空间污染)欢迎来到ADL,在那里可以找到
std::sort
,因为
std::begin
生成的迭代器位于
std
命名空间中,拉入
std::sort
。依赖于参数的查找-基本上,对于非限定函数调用,查找参数的命名空间、它们的模板参数、它们的基类,还有他们的狗的名字空间——曾曾祖母。很好的解释。我只想指出,选择名称
sort
是经过深思熟虑的,因为我想坚持使用标准库界面。我知道标准库的实现会更好,但正如前面提到的,整个项目是
    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));