Reputation: 3934
I wondered how std::vector::begin()
or similar methods could actually be overloaded for different return types (const and non const iterators), as in
std::vector<int>::iterator it = vect.begin();
and std::vector<int>::const_iterator cit = vect.begin();
Because, functions that differ only in their return type cannot be overloaded. Then I had a peek into stl_vector.h
and found that this is possible because of one of the functions is const
.
324 /** |
325 * Returns a read/write iterator that points to the first |
326 * element in the %vector. Iteration is done in ordinary |
327 * element order. |
328 */ |
329 iterator |
330 begin() |
331 { return iterator(this->_M_impl._M_start); } |
332 |
333 /** |
334 * Returns a read-only (constant) iterator that points to the |
335 * first element in the %vector. Iteration is done in ordinary |
336 * element order. |
337 */ |
338 const_iterator |
339 begin() const |
340 { return const_iterator(this->_M_impl._M_start); } |
341 |
342 /** |
343 * Returns a read/write iterator that points one past the last |
344 * element in the %vector. Iteration is done in ordinary |
345 * element order. |
346 */ |
Then I tried mimicking this structure in a test program, but am getting an error which puzzles me, as the logic looks identical to me:
struct A
{
};
struct B
{
};
struct C
{
A f() const {
std::cout << "A" << "\n";
return A();
}
B f() {
std::cout << "B" << "\n";
return B();
}
};
int main(){
C c;
A x = c.f();
}
error: no viable conversion from 'B' to 'A'
A x = c.f();
The method returning a B
is called, why doesn't the compiler deduce from A x
that the other method needs to be called and what is the difference between my test program and the stl_vector code?
Upvotes: 2
Views: 64
Reputation: 227418
You're not seeing an overload, but rather, a conversion between the relevant iterator
and const_iterator
types:
std::vector<int>::const_iterator cit = vect.begin();
If vect
is non-const, then vect.begin()
returns a vector<int>::iterator
, which can then be converted to vector<int>::const_iterator
. The reverse conversion is not allowed, for const correctness reasons.
This is largely unrelated to the issue of const
qualification of member functions, which does permit overloading.
Upvotes: 2