14

我用相同的参数列表重载了一个运算符两次。但返回类型不同:

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

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

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

谢谢

4

3 回答 3

26

这些函数不会互相重载;它们具有相同的签名,因此尝试重新定义相同的函数,这是一个错误。返回类型不是函数签名的一部分。要重载一个函数,您必须声明另一个具有相同名称但参数或const/volatile限定符不同的函数 - 即函数上的限定符,而不是返回类型。

(它们也不会相互覆盖;覆盖是派生类对其基类的虚函数所做的事情)。

定义成员函数的aconst和 non-重载是很常见的;重载必须声明函数,const而不仅仅是返回类型:constconst

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
于 2012-10-03T01:21:09.333 回答
3

您不能基于返回类型重载函数/方法。我希望编译器在这里抛出一个错误。您可以做的是将方法本身指定为const方法,使用

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

const限定符不仅意味着可以在接收器上调用它const,而且还用于重载解决方案。*this发生这种情况是因为它影响了传递给方法的隐式参数;方法在上const使用const限定符*this,并且const在重载解析期间会考虑限定符。

于 2012-10-03T01:20:29.993 回答
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&
于 2012-10-03T01:44:52.223 回答