0

我对下面的代码有疑问。当我编译它时,它会在下面抱怨这个错误。现在我的问题是,如果我删除声明中的“const”并将其更改为 only:

template<class T> T max( T& left, T& right);

一切正常,编译/执行正确。编译器怎么会认为调用是模棱两可的?前向声明不应该跟随实现吗?

==== start of error message====
max.cpp:10:34: error: call of overloaded ‘max(int, int)’ is ambiguous
max.cpp:10:34: note: candidates are:
max.cpp:5:21: note: T max(const T&, const T&) [with T = int]
/usr/include/c++/4.6/bits/stl_algobase.h:210:5: note: const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]
max.cpp:11:44: error: call of overloaded ‘max(double, double)’ is ambiguous
max.cpp:11:44: note: candidates are:
max.cpp:5:21: note: T max(const T&, const T&) [with T = double]

=======end of error message===

=============代码从这里开始======

#include<iostream>

using namespace std;

template<class T> T max(const T& left, const T& right);

int main(void)
{

      cout<<"max int:"<<  max(1,4)<<endl;
      cout<<"max double:"<<  max(5.02,1.002)<<endl;

}

template<class T>
T max(const T& left, const T& right)
{

      return left > right? left:right;
}
4

4 回答 4

5

你所要做的:

  cout<<"max int:"<<  ::max(1,4)<<endl;
  cout<<"max double:"<<  ::max(5.02,1.002)<<endl;

由于max在命名空间中定义了另一个std。您必须通知编译器使用您max定义的全局命名空间中定义的名称。在此处查看实时示例:函数模板演示

如果您查看std::maxstd 命名空间中的定义:

template <class T> const T& max (const T& a, const T& b);

它返回 const 引用并对参数进行 const 引用,这就是为什么当你删除 const 时,它会编译。希望这会有所帮助。

于 2013-05-28T03:45:06.967 回答
0

std 命名空间已经内置了一个 max,因此您可以没有该行using namespace std;或将 max 函数放在您自己的命名空间中。

namespace myNamespace {  
    //your max function  
}
于 2013-05-28T03:47:55.053 回答
0

正如其他人所写的那样,编译器在命名空间 std 中还发现了一个 max 函数。现在它试图通过函数重载为您获得最佳版本。由于两个签名都是相同的,因此无法选择最佳版本并抱怨。现在,如果您删除 const,编译器无法将整数(或双精度)文字绑定到非 const 引用。现在它只有一个选择,并采用 std::max 功能。您可以通过以下示例看到它:

#include <iostream>

namespace ns1 {

    template<class T>
    void doit(T const&) {
        std::cout << "ns1::doit" << std::endl;
    }
}

template<class T>
void doit(T&) {
    std::cout << "::doit" << std::endl;
}

int main() {
    using namespace ns1;
    int i=1;
    int const j=1;
    doit(1);
    doit(i);
    doit(i+1-1);
    doit(j);
    return 0;
}

由于everithing 是一个int,编译器只有在它有一个非常量变量(i)时才必须选择一个非常量引用。在其他情况下,它从命名空间 ns1 中选择 cont 引用版本。它甚至可以将临时对象绑定到 const 引用 (i+1-1)。max 和 std::max 也是如此。

编辑

我忘了说,如果您在声明中删除 const,编译器会选择 std::max 这当然是正确的,但不是您的。

于 2013-05-28T07:38:11.003 回答
0

我们已经在 std 命名空间中定义了一些函数,例如 max()、swap() qsort()。所以当你定义自己的函数时

max(const T& left,const T& right)

它与 std 命名空间中的一个相同,因此出现错误。因此,您可以执行以下操作以使其正常工作

  1. 使用范围解析运算符::max(x,y)调用您的函数

  2. 从函数中删除 const 限定符

于 2013-05-28T04:00:58.057 回答