как работает перегрузка константных и неконстантных функций? - PullRequest
14 голосов
/ 24 февраля 2011

Stl полон определений, подобных этому:

iterator begin ();
const_iterator begin () const;

Поскольку возвращаемое значение не участвует в разрешении перегрузки, единственная разница здесь заключается в функции const.Это часть механизма перегрузки?Каков алгоритм компилятора для разрешения строки как:

vector<int>::const_iterator it = myvector.begin();

Ответы [ 6 ]

10 голосов
/ 24 февраля 2011

«Алгоритм» компилятора выглядит так: Каждая функция-член класса X имеет неявный аргумент типа X & (я знаю, большинство думает, что это X *, но стандарт утверждает, что для целей разрешения перегрузки мы предполагаем, что он является ссылкой). Для константных функций тип аргумента - const X &. Таким образом, алгоритм, если функция-член называется двумя версиями, const и non-const, является жизнеспособным кандидатом, и наилучшее совпадение выбирается так же, как и в других случаях разрешения перегрузки. Без магии:)

10 голосов
/ 24 февраля 2011

В приведенном вами примере:

vector<int>::const_iterator it = myvector.begin();

, если myvector не совпадает, будет вызвана неконстантная версия begin(), и вы будете полагаться на неявное преобразование из итератора вconst_iterator.

4 голосов
/ 24 февраля 2011

Да, модификатор const влияет на перегрузку. Если myvector равен const, в этот момент будет вызвана версия const:

void stuff( const vector<int>& myvector )
{
    vector<int>::const_iterator it = myvector.begin(); //const version will be called
}

vector<int> myvector;    
vector<int>::const_iterator it = myvector.begin(); //non-const version will be called
3 голосов
/ 24 февраля 2011

Из стандарта C ++ (§13.3.1 Функции-кандидаты и списки аргументов):

For non-static member functions, the type of the implicit object parameter is “reference to cv X” where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration. [Example: for a const member function of class X, the extra parameter is assumed to have type “reference to const X”. ]

Итак, в вашем случае, если myvector объект равен const, компилятор выберет версию begin, которая имеет неявный параметр объекта типа reference to const vector, который является константной версией begin.

2 голосов
/ 26 августа 2014

Стоит отметить, что c ++ допускает перегрузку методов / функций const (например, foo () const), но не аргументы const перегрузка (например, bar (int a) и bar (const)int a)).

1 голос

Компилятор определяет, является ли переменная объекта постоянной или нет во время компиляции

Затем выбирается соответствующая перегрузка и любой тип возвращаемого значения.

class C {
    public:
        int f() { return 1; }
        float f() const { return 1.5; }
};

// Non const.
C c;
assert(c.f() == 1);

// Convert variable const at compile time.
assert(const_cast<const C&>(c).f() == 1.5);

// Same as above but with an explicit reference.
const C& d = c;
assert(d.f() == 1.5);

// Analogous but with a new const object from the start.
const C e;
assert(d.f() == 1.5);
...