Lan Pac
Lan Pac

Reputation: 375

Class member function behaviour when calling const objects

I have the following piece of code

#include <string>

int Foo(const std::string& str){

    std::string::iterator start;

    start = str.begin();

    return 0;
}

When i compile it with GCC 4.7.3 i receive an error.As i suspect the error pops up because i am trying to assign a

std::string::const_iterator; 

to an

std::string::iterator

So changing the line

std::string::iterator start; 

To

std::string::const_iterator start;

Compiles it finely.

My question is how the std::string member function begin() recognises that the object it is being called by is const and so returns a const_iterator.

Making the question more general:
Can i change or somehow overload a class member function to act differently when being called by a const object?

Upvotes: 0

Views: 807

Answers (3)

jrok
jrok

Reputation: 55395

My question is how the std::string member function begin() recognises that the object it is being called by is const and so returns a const_iterator.

There are two overloads of begin:

iterator       begin();
const_iterator begin() const;

Which one gets chosen depends on the type of the implicit this parameter when you call a member function - in your case it's either std::string& or const std::string&.

n3337, 13.3.1

2 The set of candidate functions can contain both member and non-member functions to be resolved against the same argument list. So that argument and parameter lists are comparable within this heterogeneous set, a member function is considered to have an extra parameter, called the implicit object parameter, which represents the object for which the member function has been called. For the purposes of overload resolution, both static and non-static member functions have an implicit object parameter, but constructors do not.

Only const qualified member function can be called on a const qualified object parameter.

How does compiler know that str is const? Well, you told it in the declaration of Foo.

Upvotes: 3

Mark Garcia
Mark Garcia

Reputation: 17708

My question is how the std::string member function begin() recognises that the object it is being called by is const and so returns a const_iterator.

The begin() method has an overload where that is const qualified that returns a const_iterator. Being const qualified means that it is the one that is used when the object it is being called from is const

iterator begin();
const_iterator begin() const;  // This one

With str being const, the second one is called, therefore the object returned is a const_iterator, the you try to assign to an iterator which is invalid and thus the error.


Can i change or somehow overload a class member function to act differently when being called by a const object?

Use auto! Instead of doing

std::string::iterator start;

start = str.begin();

Do

auto start = str.begin();

With that, you are actually using the exact type of what is being returned by begin().

However, you may be doing things the wrong way, as whether you need a const or non-const iterator depends on the task you want to achieve. As a general guideline, always use const iterators unless you intend to modify the elements inside the container.

Upvotes: 0

Konstantin
Konstantin

Reputation: 2629

The compiler automatically selects a const member function if your object is const.

You will have to provide two member functions:

void someMethod();
void someMethod() const;

Upvotes: 0

Related Questions