C ++重载运算符两次,一次返回非const引用和另一个const引用,有什么偏好?

时间:2012-10-03 01:14:48

标签: c++ reference operator-overloading const operator-keyword

我使用相同的参数列表重载操作符两次。但具有不同的返回类型:

T& operator()(par_list){blablabla}    
const T& operator()(par_list){blablabla}

所以当我调用()运算符时,会根据什么偏好或情况调用哪个函数?我知道如果我在const函数下调用()它必须是const T&之一。

我只是好奇C ++如何处理这种情况以及默认偏好如何工作。

由于

3 个答案:

答案 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&