错误:调用重载函数‘max(int, int)’不明确。

7
#include <iostream>

using namespace std;

template<typename T>
T max(T lhs, T rhs)
{
  return lhs < rhs ? rhs : lhs;
}
template<>
int max<int>(int lhs, int rhs)
{
  return lhs < rhs ? rhs : lhs;
}

int main()
{
  cout << max<int>(4, 5) << endl;

}

~/Documents/C++/boost $ g++ -o testSTL testSTL.cpp -Wall
testSTL.cpp: In functionint main()’:
testSTL.cpp:18:24: error: call of overloaded ‘max(int, int)’ is ambiguous
testSTL.cpp:11:5: note: candidates are: T max(T, T) [with T = int]
/usr/include/c++/4.5/bits/stl_algobase.h:209:5: note:                 const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]

如何纠正这个错误?


3
移除 using namespace std; - Mr Lister
3
因为英语不是我们许多人的母语。 - Armen Tsirunyan
2
@VJovic:这不是借口。在学习其他英语知识的同时,也应该学会正确提问的方式。我不明白为什么任何人,无论是母语为英语还是非英语人士,都会认为“如何纠正这个错误”是一个合理的问题结构。 - Lightness Races in Orbit
4
在这个网站上,并非每个人都是以英语为母语的,因此很难感知表达的真正含义。至少最终的目标已经达成:你理解了他所问的内容。 :) - ereOn
@LightnessRacesinOrbit:作为一个法语母语者,“如何纠正这个错误”是“Comment corriger cette erreur?”的逐字翻译,完全合理。现在OP似乎住在芝加哥,所以我不确定我的观点是否正确。 - ereOn
显示剩余8条评论
6个回答

21

这全是由于你的using namespace std;导致的。移除掉这行代码。 这个using命令会将std::max引入到全局作用域中(其中必须是通过iostream头文件包含)。因此编译器不知道要调用哪个max——::max还是std::max

我希望这个例子能够提醒那些认为using命令没有代价的人。奇怪的错误就是其负面影响之一。


2
@stinky472:ADL是标准。不支持它的编译器应该被扔掉。 - Armen Tsirunyan
1
@stinky472:Sutter在很多书中都有很多关于为什么不要做这个或那个的章节,因为虽然它是标准,但msvc不能正确地处理它。这一切都是由FUD驱动的,应该把压力放在编译器人员身上,让他们修复自己的东西,而不是让程序员使用丑陋的解决方法。ADL在主要的开源编译器中运行良好。 - PlasmaHH
ADL的规则显然不是我理解的。所有合理的编译器都提供ADL,仅仅是为了支持“hello world”示例,但“如何”是我们进入未定义领域的地方。尽管Sutter提出了反对意见,但我还是认为使用指令是有益的。 - stinky472
1
@LightnessRacesinOrbit:当然不会。ADL的发明主要是因为操作符的问题,所以完全可以依赖于ADL。 - Armen Tsirunyan
2
@stinky472:ADL规则在C++标准中定义得很清楚,而且它们比重载解析或模板实例化点的规则要简单得多。我认为不依赖ADL是一种不好的做法,而不是相反。 - Armen Tsirunyan
显示剩余12条评论

5

我猜编译器无法确定使用std :: max还是您的max,因为您有一个using namespace std;,而且您的max和std :: max都符合要求。


4

您正在与std::max()发生冲突。将其重命名为其他名称,例如mymax,它就能正常工作。


3
最好不要在std命名空间中定义它,就像Armen提到的那样。 - FatalError
3
OP从未将其定义在std命名空间中。我建议不要将std命名空间的所有名称带入全局范围。 - Armen Tsirunyan
将标准库放在std命名空间中的整个目的是,您可以在其他命名空间(或全局)中定义自己的max函数,或者通常不必不断思考哪些名称用于标准(或任何其他)库。如果您不使用它们来解决命名冲突并继续使用前缀,那么首先使用命名空间的意义是什么?! - UncleBens

4

你有两个函数名都是maxstd::max。编译器不知道你想调用哪一个。

你可以通过调用::max(4,5)std::max(4,5)来告诉它,或者更好的方法是在文件中不使用using namespace std


3
那是因为已经定义了std::max模板函数。 移除'using namespace std'并在需要的地方添加'std::',或者使用'::max'。

2

问题在于std已经定义了一个名为“max”的函数。为了解决这个问题,将您的函数重命名为其他名称,例如:

#include <iostream>

using namespace std;

template<typename T>
T mymax(T lhs, T rhs)
{
    return lhs < rhs ? rhs : lhs;
}
template<>
int mymax<int>(int lhs, int rhs)
{
    return lhs < rhs ? rhs : lhs;
}

int main()
{
    cout << mymax<int>(4, 5) << endl;

    return 0;
}

不要再使用 using namespace std - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接