Reputation: 375
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
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
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
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