С++ перегрузите оператор дважды, один возвращает неконстантную ссылку и другую ссылку на константу, каково предпочтение?
Я дважды перегружаю оператор с тем же списком параметров. но с другим типом возврата:
T& operator()(par_list){blablabla}
const T& operator()(par_list){blablabla}
Итак, когда я вызываю оператор(), какая функция будет вызываться на основе каких предпочтений или ситуации? Я знаю, что если я вызываю() при функции const, это должен быть const T & один.
Мне просто интересно, как С++ справляется с такой ситуацией и как работает настройка по умолчанию.
Спасибо
Ответы
Ответ 1
Эти функции не перегружают друг друга; они имеют одинаковые сигнатуры, и поэтому попытка переопределить ту же функцию, которая является ошибкой. Тип возврата не является частью сигнатуры функции. Чтобы перегрузить функцию, вы должны объявить вторую функцию с тем же именем, но разные параметры или 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
Ответ 2
Вы не можете перегружать функцию/метод на основе типа возврата. Я ожидаю, что компилятор будет здесь делать ошибку. Что вы можете сделать, так это указать метод как метод const
, используя
const T& operator()(par_list) const {blahblah}
Квалификатор const
не только означает, что это можно вызвать в приемнике const
, но также используется в разрешении перегрузки. Это происходит потому, что это влияет на неявный параметр *this
, который передается методу; a const
использует квалификатор const
на *this
, а квалификаторы const
учитываются при разрешении перегрузки.
Ответ 3
То, как вы определяете своих операторов, никак не может решить, какой оператор() вызывать. Перегрузка функций (и операторов) может выполняться только по типу аргументов, а не по типу возврата. И на самом деле у вас будет ошибка при компиляции, как только вы определите вторую, компилятор, считая, что вы переопределяете одну и ту же функцию/оператор.
Однако, общее (и, вероятно, то, что у вас есть):
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&