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

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Gurinderc
    New Member
    • Sep 2010
    • 4

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

    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
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    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.

    Comment

    • Gurinderc
      New Member
      • Sep 2010
      • 4

      #3
      Thanks for looking into, this sample code -
      Code:
      class A
      {
      	int l;
      	const int m;
      public:
      	A() : l(10), m(15){};
      	const A* function(void) const
      	{
      		cout<<"Const "<<endl;
      		return this;
      	}
      
      	A* function(void)
      	{
      		cout<<"Non Const "<<endl;
      		return this;
      	}
      };
      
      int main()
      {
      	A a;
      	const A *a = a.function();
      	return 0;
      }
      Never call the first member function i.e. const A* function(void) const. What change I need to do to make it work.

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        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.

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Iterators in the STL are nested classes:

          Code:
          class X
          {
              public:
                class const_iterator
                {
          
                };
          
          };
          
          class Y
          {
              public:
                class const_iterator
                {
          
                };
          
          };
          The compiler sees X::const_oterat or as a separate object from Y::const_iterat or.

          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_iterat or::operator=(X ::terator&) function and a
          Y::const_iterat or::operator=(Y ::terator&) function.

          Comment

          • Oralloy
            Recognized Expert Contributor
            • Jun 2010
            • 988

            #6
            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:
            Code:
            int main() 
            { 
                A a;
                A const &b = a;
                const A *c = b.function(); 
                return 0; 
            }

            Comment

            Working...