模板函数调用歧义错误

Des*_*tor 11 c++ templates ambiguity ambiguous ambiguous-call

我不熟悉模板.我刚开始学习它.为什么我在以下程序中遇到错误?

#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;
}
Run Code Online (Sandbox Code Playgroud)

错误:

13  [Error] call of overloaded 'min(std::string&, std::string&)' is ambiguous

6   [Note] C min(C, C) [with C = std::basic_string<char>]
Run Code Online (Sandbox Code Playgroud)

请帮我.

Yak*_*ont 14

这里有两件事.

您的第一个问题是您只包含部分错误消息. 这是一个链接到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) {
  ^
Run Code Online (Sandbox Code Playgroud)

有两个候选人.一个在main.cpp:6:3(第6行,第3个字符)和第一个algorithm:2579:1(第2579行,第1个字符).

你写的其中一个,其中一个在#include <algorithm>.

<algorithm>没有要求它的一个头文件包括在内.标准头文件允许执行此操作,因为它有时很烦人.

<algorithm>那里有一个std::min功能模板.作为std::string模板类的实例,通过称为"参数依赖查找"或"Koenig查找"的过程找到namespace std函数模板std::min.(函数重载候选者在本地搜索,也在函数参数的名称空间中搜索,并在函数参数的模板参数的名称空间中,以及在参数指向的事物的名称空间中搜索.功能等)

您的本地函数min也被找到,因为它与正文的主体名称相同main.

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

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

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

  • 或者做`(min)(a,b)`:) (2认同)

Cor*_*mer 5

你正在与一个名字碰撞std::min.它可能包含在您包含的其他标准库标题之一中,<iostream>或者<string>,我的猜测可能是后者.快速解决方法是重命名您的功能.例如,将其重命名为mymin正常工作.演示

  • 你不需要,因为`std :: string`在标准库命名空间中,它将通过参数依赖查找(ADL)解析`std :: min`. (2认同)