Why only fickle maps provide an associative search for elements in an array?

I read:

C ++ Standard Library: a tutorial and reference book by Nikolai M. Jossuttis

This is my book when I am going to use some STL mechanisms in any significant way. In any case, I quickly re-read the chapters on std :: map and related algorithms, and I noticed a sentence that I had not thought about before:

Volatile maps provide an index operator for direct access to an element. However, the index operator index is not an integral position of an element .... etc.

Why can only mutable maps be used in an associative array? It seems that in this case it would be pretty simple to provide read-only semantics. I believe that exceptions would be possible if you tried to retrieve an element with a key that was not there (sine you cannot add a new key / value to the map if its constant).

I would like to understand the reasons for this if someone can shed some light :) thanks!

+6
source share
4 answers

Why in the associative array can only non-constant cards, such as images, be used?

Because these operators return a reference to the object associated with a particular key. If the container does not already contain such an object, operator[] inserts the default object. Now, if the container is persistent, you cannot insert any objects into it, and you cannot return a link to non-existent objects, therefore these operators are available only for mutable containers.

Throwing an exception in this case is possible, of course, but not the best way to approach fairly general cases when an object for a given key does not exist. In principle, exceptions are extremely expensive and are designed for exceptional situations, but above are not, so this is not worth it.

The best way would be to return the iterator, but then the user would have to check if it is "complete", which would make the use case look like a find () call, and therefore useless. Return iterators or pointers are also possible for containers with persistent content, but this confuses semantics a bit and confuses them.

+11
source

In C ++ 11, you can use at() to get the behavior "get the mapped value, otherwise throw an exception." Overloading operator[] to perform two different actions (for example, inserting a new pair or throw) depending on whether the map is constant, will be too confusing and error prone.

+8
source

The [] operator mutates the container: if the key does not exist, it will be created:

 return m[1]; // **creates** m[1] if it doesn't exist return *m.find(1) // UB if m[1] doesn't exist (dereferencing m.end()) 

In addition, [] always returns a mutable reference, so you can say m[1] = 2; . On the other hand, find() returns an iterator whose constant is the map itself:

 map_t m; *m.find(1) = 2; // Only OK if m[1] exists // *const_cast<map_t const &>(m).find(1) = 2; // error 
+1
source
Operator

[] changes the map if the key does not exist.

If the key does not exist, the card creates a new record with the key and the default value for the associated value and returns its reference. For this, operator[] must be a non-constant function, which means that it cannot work with an instance of const std::map .

+1
source

Source: https://habr.com/ru/post/902677/


All Articles