Re: need for operator[] in map
James Kanze wrote:
On Feb 7, 3:56 pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.com> wrote:
For inserting new elements in map, we can use insert member function.
To know if an element exists or not in a map, we can use count or find
member function.
Also, we can use the iterator returned by find to modify the mapped
value of an existing key.
When we use operator[], it may add an element into the map if the key
already doesn't exist, which may not be always wanted.
Given this, I am unable to understand the reason as to why we have
operator[] in map whose functionality can be achieved by other member
functions.
Convenience. It's a bit awkward, in that the semantics which
would be most convenient vary according to what you're using the
map for, and in practice, I rarely use []. (But then, most of
my maps are const, so I can't.) The real question is, of
course, if [] doesn't find the element, what does it do?
Well, the language does not really give you a chance here. Suppose you
wanted to not insert a default or dummy value into the map, what would you
return? Maybe a proxy like so:
#include <map>
#include <cassert>
#include <iostream>
#include <utility>
template < typename Key, typename Mapped >
struct does_not_work
: public std::map< Key, Mapped > // hack!
{
typedef typename std::map< Key, Mapped >::iterator iterator;
class proxy {
does_not_work * map_ptr;
Key const * key_ptr;
iterator where;
public:
proxy ( Key const & the_key, does_not_work & the_map )
: map_ptr ( &the_map )
, key_ptr ( &the_key )
, where ( map_ptr->find( the_key ) )
{}
operator Mapped & ( void ) {
assert( where != map_ptr->end() );
return ( where->second );
}
operator Mapped const & ( void ) const {
assert( where != map_ptr->end() );
return ( where->second );
}
Mapped & operator= ( Mapped const & other ) {
if ( where == map_ptr->end() ) {
where = map_ptr->insert( std::make_pair( *key_ptr, other ) ).first;
} else {
where->second = other;
}
return ( where->second );
}
Mapped & operator= ( proxy const & other ) {
return ( this->operator=( static_cast< Mapped const & >( other ) ) );
}
};
proxy operator[] ( Key const & key ) {
return ( proxy( key, *this ) );
}
};
int main ( void ) {
does_not_work< int, int > my_map;
my_map[3] = 5;
std::cout << my_map[3] << '\n';
std::cout << my_map[0] << '\n'; // triggers assert, could be made throwing
}
However, that is not really satisfying when it comes to syntactic sugar:
my_map[key].some_method();
for instance cannot be done since we cannot overload the dot-operator.
Because of that, we cannot have smart-references as a complement to smart
pointers and proxy object can fall short of desires and expectations.
[snip]
Best
Kai-Uwe Bux