模板函数调用歧义错误

Template function call ambiguity error

我对模板不熟悉。我刚刚开始学习它。为什么我在执行以下程序时出错?

#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>]

请帮帮我

您 运行 与 std::min 发生名称冲突。它可能包含在您包含的其他标准库 headers 中,<iostream><string>,我猜可能是后者。快速修复是重命名您的函数。例如,将其重命名为 mymin 就可以了。 Demo

这里发生了两件事。

您的第一个问题是您只包含了错误消息的一部分。 Here is a link to the code being complied in gcc and 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>.

您的 header 个文件包含 <algorithm> 而您没有要求。允许标准 header 执行此操作,尽管有时很烦人。

<algorithm>中有一个std::min函数模板。由于 std::stringnamespace std 中模板 class 的一个实例,函数模板 std::min 是通过名为 "argument dependent lookup" 或 "Koenig lookup" 的过程找到的。 (在本地搜索函数重载候选者,也在函数参数的命名空间中,在函数参数的模板参数的命名空间中,以及在参数指向的事物的命名空间中功能等)

您的本地函数 min 也已找到,因为它与 main 的 body 在同一个命名空间中。

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

gcc 和 clang 都执行 error: 然后是一系列 note:。通常错误发生后 note: 秒中的 all 对于理解错误很重要。

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