使用模板时C++ "const"神秘重载函数调用
when using templates C++ "const" mystery overloaded function call
我对下面的代码有一个问题。当我编译它时,它报错如下。现在我的问题是,如果我删除声明中的"const"并将其更改为:
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;
}
你必须这样做:
cout<<"max int:"<< ::max(1,4)<<endl;
cout<<"max double:"<< ::max(5.02,1.002)<<endl;
因为在std
命名空间中定义了另一个max
。您必须通知编译器使用全局命名空间中定义的max
,这是您定义的。函数模板Demo
如果您查看std名称空间中定义的std::max
:
template <class T> const T& max (const T& a, const T& b);
返回const引用并接受const引用作为形参,这就是为什么当你删除const时,它会编译。
std名称空间已经内置了max,因此您可以不使用using namespace std;
行,也可以将max函数放在您自己的名称空间中。
namespace myNamespace {
//your max function
}
在std命名空间中已经定义了几个函数,如max(), swap()和qsort()。所以当你定义自己的函数
时max(const T& left,const T& right)
与STD命名空间中的相同,因此出现错误。因此,您可以执行以下操作来使其工作
使用范围解析运算符::max(x,y)
调用函数从函数中删除const限定符
正如其他人所写的那样,编译器在命名空间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;
}
因为一切都是int,编译器必须选择非const引用,只有当它有一个非const变量(i)时。在其他情况下,它从命名空间ns1中选择const引用版本。它甚至可以将临时对象绑定到const引用(i+1-1)。max和std::max也是一样。
编辑:
我忘了说如果你在你的声明中删除const编译器选择std::max这当然是正确的,但不是你的
- 在运算符重载定义中使用成员函数(const错误)
- 在gcc中意外调用了Const重载.编译器错误或兼容性修复程序
- 关于重载 -> 运算符中 const 关键字的特定位置的问题
- 使用 bool 和 const char 重载的 C++ 函数会在没有警告的情况下产生歧义 (MSVC2012)
- 在函数中使用运算符重载,在 c++ 中使用 const 类型输入参数
- 在运算符重载中使用带有 const 引用的 friend 函数
- 如何在 std::map<const int、int> C++ 中重载插入运算符>>?
- 为什么重载运算符>在参数声明 const 时不起作用?
- 将 const QByteArray 传递给重载函数
- 重载 * 运算符时不使用 const 的影响
- std::result_of 应用于 const 重载方法
- 编译器如何知道是否调用 const 重载
- 我只能有const重载的运算符成员函数
- const重载,而不必写入函数两次
- 如何在没有重复代码的情况下实现"const"和"non-const"重载?
- gsl::span<T> 和 gsl::span<const T> 重载不明确
- std::begin和std::end的const重载的目的是什么
- 避免const重载和RVO的代码重复
- c++ const重载赋值操作符机制
- 使用声明和const重载