模板函数调用模糊性错误

Template function call ambiguity error

本文关键字:错误 模糊性 函数调用      更新时间:2023-10-16

我不熟悉模板。我刚开始学习。为什么我在下面的程序中会出错?

#include <iostream>
#include <string>
using std::cout;
using std::string;
template<class C>
C min(C a,C b) {
    return a<b?a:b;
}
int main()
{
    string a="first string";
    string b="second string";
    cout<<"minimum string is: "<<min(a,b)<<'n';
    int c=3,d=5;
    cout<<"minimum number is: "<<min(c,d)<<'n';
    double e{3.3},f{6.6};
    cout<<"minimum number is: "<<min(e,f)<<'n';
    char g{'a'},h{'b'};
    cout<<"minimum number is: "<<min(g,h)<<'n';
    return 0;
}

错误:

13  [Error] call of overloaded 'min(std::string&, std::string&)' is ambiguous
6   [Note] C min(C, C) [with C = std::basic_string<char>]

请帮帮我。

这里有两件事。

您的第一个问题是您只包含了错误消息的一部分。这里有一个链接,指向gcc和clang中正在编译的代码,以及由此产生的错误消息之一(完整(:

main.cpp:13:34: error: call to 'min' is ambiguous
    cout<<"minimum string is: "<<min(a,b)<<'n';
                                 ^~~
/usr/include/c++/v1/algorithm:2579:1: note: candidate function [with _Tp = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >]
min(const _Tp& __a, const _Tp& __b)
^
main.cpp:6:3: note: candidate function [with C = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >]
C min(C a,C b) {
  ^

有两位候选人。一个位于main.cpp:6:3(第6行,字符3(,另一个位于algorithm:2579:1(第2579行,字符1(。

其中一个是你写的,还有一个是#include <algorithm>

你的一个头文件在没有要求的情况下包含了<algorithm>。标准的头文件可以这样做,尽管有时很烦人。

<algorithm>中有一个std::min函数模板。由于std::stringnamespace std中模板类的一个实例,因此函数模板std::min是通过一个称为"参数相关查找"或"Koenig查找"的过程找到的。(函数重载候选者在本地搜索,也在函数参数的名称空间、函数参数的模板参数的名称名称空间以及函数参数所指向的事物的名称空间等中搜索。(

还可以找到本地函数min,因为它与main的主体位于同一命名空间中。

两者都是同样好的匹配,编译器无法决定要调用哪一个。所以它会产生一个错误告诉你这一点。

gcc和clang都执行error:,然后执行一系列note:s。通常错误后的所有note:s对于理解错误很重要。

要解决此问题,请尝试调用::min(完全限定调用(,或者将函数重命名为其他函数,或者使您的版本比std::min更好地匹配(虽然很棘手,但在某些情况下是可行的(,或者调用(min)(a,b)。最后一个阻止ADL/Koenig查找,也阻止宏扩展(例如,如果某些操作系统已将#define min宏注入其系统标头((通过@0x499602D2(。

您遇到了与std::min的名称冲突。它可能包含在您包含的其他标准库头中,<iostream><string>,我猜可能是后者。快速解决方法是重命名您的函数。例如,将其重命名为mymin就可以了。演示