为什么模板函数调用是不明确的

Why Template Function call is ambiguous?

本文关键字:不明确 函数调用 为什么      更新时间:2023-10-16
#include <iostream>
using namespace std;
template <typename T>
T max(T x, T y)
{
    return (x > y) ? x : y;
}
int main()
{
    cout << max(3, 7) << std::endl;
    cout << max(3.0, 7.0) << std::endl;
    cout << max(3, 7.0) << std::endl;
    return 0;
}

我在这里等待max的实例

cout << max(3, 7) << std::endl; // max (int, int)
cout << max(3.0, 7.0) << std::endl; // max (double, double)
cout << max(3, 7.0) << std::endl; // max(int, double)

那是什么问题?为什么我得到

11 25 [Error] call of overloaded 'max(double, double)' is ambiguous

如果完整地查看编译错误,就会明白原因。下面是gcc 5.2给我的:

main.cpp: In function 'int main()':
main.cpp:10:21: error: call of overloaded 'max(int, int)' is ambiguous
     cout << max(3, 7) << std::endl;
                     ^
main.cpp:4:3: note: candidate: T max(T, T) [with T = int]
 T max(T x, T y)
   ^
In file included from /usr/local/include/c++/5.2.0/bits/char_traits.h:39:0,
                 from /usr/local/include/c++/5.2.0/ios:40,
                 from /usr/local/include/c++/5.2.0/ostream:38,
                 from /usr/local/include/c++/5.2.0/iostream:39,
                 from main.cpp:1:
/usr/local/include/c++/5.2.0/bits/stl_algobase.h:219:5: note: candidate: constexpr const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]
     max(const _Tp& __a, const _Tp& __b)
     ^

基本上,有两个max函数-你的和std::max,它包含在<iostream>的其他#include链中。后者是通过查找找到的,因为您的

using namespace std;

实际上,我们有:

template <typename T> T max(T, T);                      // yours
template <typename T> T const& max(T const&, T const&); // std

两者都不如另一个,因此是二义性的。这是避免using namespace std的一个很好的理由。或者,当涉及到标准库函数时,不需要重新发明轮子的一个很好的理由-只使用std::max。或两者兼而有之。


另一方面,这个

max(3, 7.0)

无论如何都将作为模板推导失败。它会将T演绎为第一个参数int,将T演绎为第二个参数double——但是只能有一个T !您必须显式调用max<int>(3, 7.0)max<double>(3, 7.0)来避免演绎失败,这取决于您想要转换的两个参数中的哪一个。

using namespace std;

肯定会让事情变得复杂。但是,即使删除了这一行,问题仍然存在。

呼叫max(3, 7.0)可以解析为max<int>max<double>。要解析为max<int>,必须将double转换为int。要解析为max<double>,必须将int转换为double。由于两者都需要转换,并且不能给其中一个转换赋予比另一个更高的优先级,因此编译器无法解析使用哪一个。

您必须明确要使用哪个版本的max

max<int>(3, 7.0)7.0 (double)转换为int

max<double>(3, 7.0)3int转换为double

Max是一个库函数。只需将函数的Max标识符更改为max1或任何其他不是定义任何头文件的函数的名称。这应该能解决你的问题。