I think you need to use a const_iterator since you are dealing with a const PhoneBook. I'd probably make the iterator inside the for loop instead of having it be a member of the class.
I can see you having an iterator member to serve as a bookmark, but in your operator>> function, you should make a copy of the iterator in the function. Either that, or pass the object by non-const reference instead of value, so you can modify the bookmark of the original object.
Think about it:
The parameter is a reference to a constant object. This means the object cannot (and should not) be modified. In your previous version of the function, you break this rule by modifying the member variable
>> I can see you having an iterator member to serve as a bookmark
No, I don't need it. I don't use the iterator us a bookmark. It's my mistake. I must use: this->it = base.begin(); in this:
// The parameter is a reference to a constant object. This means the object cannot (and should not) be modified. In your previous version of the function, you break this rule by modifying the member variable
it
in the loop.
Why the compile don't inform me about the error "the object cannot (and should not) be modified" in this example:
Your parameter is a constant object. Constants are constant; they cannot be modified, and any member of a constant object should also be constant (or read only for functions).
Now look at your for loop:
Here you modify a member of pb. But pb is constant, meaning pb.it, too, should be constant.
That's what the error means by "discards [const] qualifier".
Considering your operator>>() function, you should just create a new iterator instead of attempting to modify pb.it.
1 2 3 4 5 6 7 8 9 10
inline std::ostream& operator<<(std::ostream& stream, const PhoneBook& pb) {
for (std::map<std::string, std::string>::const_iterator iter = (pb.base.begin()); iter != (pb.base.end()); ++iter) {
stream << iter->first << ": " << iter->second << std::endl;
}
//There is also the C++11 auto keyword redefinition, which would let you write
//for (auto iter = (pb.base.begin()); iter != (pb.base.end()); ++iter) {
//The type should be the same because begin() members return a
// const_iterator when called with a const object
return stream;
}
//There is also the C++11 auto keyword redefinition, which would let you write
//for (auto iter = (pb.base.begin()); iter != (pb.base.end()); ++iter) {
//The type should be the same because begin() members return a
// const_iterator when called with a const object
I read about it in the book "Professional C++," 2 edition. I like this book. Thank you!