我使用相同的参数列表重载操作符两次。但具有不同的返回类型:
T& operator()(par_list){blablabla}
const T& operator()(par_list){blablabla}
所以当我调用()运算符时,会根据什么偏好或情况调用哪个函数?我知道如果我在const函数下调用()它必须是const T&之一。
我只是好奇C ++如何处理这种情况以及默认偏好如何工作。
由于
答案 0 :(得分:24)
这些功能不会相互过载;它们具有相同的签名,因此尝试重新定义相同的函数,这是一个错误。返回类型不是函数签名的一部分。要重载函数,必须声明具有相同名称但不同参数或const
/ volatile
限定符的第二个函数 - 即函数的限定符,而不是返回类型。
(它们也不会互相覆盖;覆盖是派生类对其基类的虚函数所做的事情。)
定义成员函数的const
和非const
重载是很常见的; const
重载必须声明函数const
,而不仅仅是返回类型:
T& operator()(par_list){blablabla}
const T& operator()(par_list) const {blablabla}
^^^^^
如果您将()
应用于非const
对象,而第二个应用于const
对象,则会调用第一个。例如:
Thingy nc;
Thingy const c;
nc(); // calls the first (non-const) overload
c(); // calls the second (const) overload
答案 1 :(得分:3)
您不能基于返回类型重载函数/方法。我希望编译器在这里抛出一个错误。您可以做的是使用
将方法本身指定为const
方法
const T& operator()(par_list) const {blahblah}
const
限定符不仅意味着可以在const
接收器上调用,还可以在重载决策中使用它。发生这种情况是因为它影响传递给方法的隐式*this
参数; const
方法在const
上使用*this
限定符,并且在重载解析期间会考虑const
限定符。
答案 2 :(得分:1)
您定义运算符的方式,编译器无法决定调用哪个operator()。函数(和运算符)的重载只能在参数类型上完成,永远不能在返回类型上完成。实际上,一旦定义了第二个编译器,编译时就会出现错误,编译器会考虑您重新定义相同的函数/运算符。
但是,以下是常见的(也可能是您所拥有的):
T& operator()(par_list){blablabla}
const T& operator()(par_list) const {blablabla}
参数列表之后的这个附加“const”存在是因为你定义了非静态成员函数,而成员函数有一个隐含的隐藏参数:指向类实例的“this”指针。 “const”关键字指示此隐藏指针是否指向const实例。这个参数参与了重载决策,在这种情况下,编译器使用它来选择使用哪个版本的运算符。
所以:
class A {
T& operator()() { ... }
const T& operator()() const { .... }
};
A a;
const A& ca(a);
a(); -> returns a T&
ca(); -> returns a const T&