By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,962 Members | 1,776 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,962 IT Pros & Developers. It's quick & easy.

How Complier Distinguish Between const_iterator begin() and iterator begin()

P: 4
Hello All,

I have a very basic question on STL Iterator implementation, I like to know :

How does complier distinguish between const_iterator begin() and iterator begin().

There are few answer's on the internet but nothing concrete. I can't find exact, might be using wrong keywords in search.

Can someone point out it, if possible with example.

Many Thanks
Sep 16 '10 #1

✓ answered by Banfa

It's not

const_interator begin();

it's

const_interator begin() const;

and that trailing const makes all the difference because you could not have both overloads

const_interator begin();
interator begin()

the compiler can not distinguish between them (since return type plays no part in distinguishing between overloads) but you can have both overloads

const_interator begin() const;
interator begin()

because the compiler can distinguish between them because of the trailing const on the first definition which the compiler does use in distinguishing overloads.

The compiler then uses the context that begin is called in to decide which of the 2 begins to call calling

const_interator begin() const;

if the context is constant and

interator begin();

otherwise.

Share this Question
Share on Google+
5 Replies


Banfa
Expert Mod 5K+
P: 8,916
It's not

const_interator begin();

it's

const_interator begin() const;

and that trailing const makes all the difference because you could not have both overloads

const_interator begin();
interator begin()

the compiler can not distinguish between them (since return type plays no part in distinguishing between overloads) but you can have both overloads

const_interator begin() const;
interator begin()

because the compiler can distinguish between them because of the trailing const on the first definition which the compiler does use in distinguishing overloads.

The compiler then uses the context that begin is called in to decide which of the 2 begins to call calling

const_interator begin() const;

if the context is constant and

interator begin();

otherwise.
Sep 16 '10 #2

P: 4
Thanks for looking into, this sample code -
Expand|Select|Wrap|Line Numbers
  1. class A
  2. {
  3.     int l;
  4.     const int m;
  5. public:
  6.     A() : l(10), m(15){};
  7.     const A* function(void) const
  8.     {
  9.         cout<<"Const "<<endl;
  10.         return this;
  11.     }
  12.  
  13.     A* function(void)
  14.     {
  15.         cout<<"Non Const "<<endl;
  16.         return this;
  17.     }
  18. };
  19.  
  20. int main()
  21. {
  22.     A a;
  23.     const A *a = a.function();
  24.     return 0;
  25. }
  26.  
Never call the first member function i.e. const A* function(void) const. What change I need to do to make it work.
Sep 16 '10 #3

Banfa
Expert Mod 5K+
P: 8,916
Well you are not calling A::function in a constant context so it is defaulting to calling the non-const A::function because the conversion A* -> const A* is completely valid.

Why do you need it to call const A* function(void) const? It would be normal practice for 2 functions like this, 1 const 1 not const to do more or less the same thing.
Sep 16 '10 #4

weaknessforcats
Expert Mod 5K+
P: 9,197
Iterators in the STL are nested classes:

Expand|Select|Wrap|Line Numbers
  1. class X
  2. {
  3.     public:
  4.       class const_iterator
  5.       {
  6.  
  7.       };
  8.  
  9. };
  10.  
  11. class Y
  12. {
  13.     public:
  14.       class const_iterator
  15.       {
  16.  
  17.       };
  18.  
  19. };
The compiler sees X::const_oterator as a separate object from Y::const_iterator.

A begin() method returns an X::iterator or a Y::iterator. To get that returned iterator into a const_iterator object, you will need an X::const_iterator::operator=(X::terator&) function and a
Y::const_iterator::operator=(Y::terator&) function.
Sep 16 '10 #5

Oralloy
Expert 100+
P: 983
Does your example even compile? I see the variable a as being defined twice.

Regardless, you can force const-ness with a cast, but I do not think that it's appropriate to do so.

C++ does not infer function signature from expected return type, it infers function signature from the argument types. There is a whole argument/discussion in the OOP world about selecting overloaded functions based on return type. Some languages do, others don't.

In your case, the implicit this argument is a non-const, as the variable a is not const. Since the only argument to function is implicitly this, in your case, the non-const form is selected.

You might try changing main to read like this:
Expand|Select|Wrap|Line Numbers
  1. int main() 
  2.     A a;
  3.     A const &b = a;
  4.     const A *c = b.function(); 
  5.     return 0; 
Sep 16 '10 #6

Post your reply

Sign in to post your reply or Sign up for a free account.