Как работает перегрузка функций const и non-const?

В stl полно таких определений:

iterator begin ();
const_iterator begin () const;

Поскольку возвращаемое значение не участвует в разрешении перегрузки, единственная разница здесь - это функция const. Является ли эта часть механизма перегрузки? Что такое алгоритм компилятора для решения такой строки, как:

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

Ответ 1

В примере, который вы указали:

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

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

Ответ 2

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

Ответ 3

Да, модификатор 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

Ответ 4

Из стандарта С++ (§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 object is const, компилятор выберет версию begin, у которой есть неявный объектный параметр типа reference to const vector, который является версией const begin.

Ответ 5

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

Ответ 6

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

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

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);