20

The STL is full of definitions like this:

iterator begin ();
const_iterator begin () const;

As return value does not participate in overloading resolution, the only difference here is the function being const. Is this part of the overloading mechanism? What is the compiler's algorithm for resolving a line like:

vector<int>::const_iterator it = myvector.begin();
Milan
  • 1,743
  • 2
  • 13
  • 36
davka
  • 13,974
  • 11
  • 61
  • 86

6 Answers6

13

In the example you gave:

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

if myvector isn't const the non-const version of begin() will be called and you will be relying on an implicit conversion from iterator to const_iterator.

Flexo
  • 87,323
  • 22
  • 191
  • 272
12

The compiler's "algorithm" is like this: Every member function of class X has an implicit argument of type X& (I know, most think it's X*, but the standard states, that for purposes of Overload Resolution we assume it to be a reference). For const functions, the type of the argument is const X&. Thus the algorithm, if a member function is called the two versions, const and non-const, are both viable candidates, and the best match is selected just as in other cases of overload resolution. No magic :)

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • thanks, this is useful, however my problem was the (wrong) assumption that the const variant is called because of the type of the variable it is assigned to. @awoodland explained this – davka Feb 24 '11 at 11:18
  • Why reference and not pointer and that too only for overload resolution, any non-obvious reason for it ? – Talespin_Kit Jan 30 '18 at 05:07
4

Yes, the const modifier affects overloading. If myvector is const at that point const version will be called:

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
sharptooth
  • 167,383
  • 100
  • 513
  • 979
3

It's worth mentioning that c++ allows const methods/functions overloading (e.g. foo() const), but not const arguments overloading (e.g. bar(int a) and bar(const int a)).

Danny
  • 51
  • 3
3

From C++ standard (§13.3.1 Candidate functions and argument lists):

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”. ]

So, in your case, if myvector object is const compiler will pick version of begin which has implicit object parameter of type reference to const vector which is const version of begin.

Bojan Komazec
  • 9,216
  • 2
  • 41
  • 51
2

The compiler determines if the object variable is const or not at compile time

It then picks the corresponding overload, and whatever return type it has.

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);
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985