Const Map Element Access

Const map element access

at() is a new method for std::map in C++11.

Rather than insert a new default constructed element as operator[] does if an element with the given key does not exist, it throws a std::out_of_range exception. (This is similar to the behaviour of at() for deque and vector.)

Because of this behaviour it makes sense for there to be a const overload of at(), unlike operator[] which always has the potential to change the map.

How to get element from const map?

The operator [] is declared for the class template std::map the following way

T& operator[](const key_type& x);
T& operator[](key_type&& x);

That is the the operator returns a non-constant reference that may not be done for a constant object. And the operator may be called only for a non-constant object because it is declared without the qualifier const.

Instead use the function at declared like

T& at(const key_type& x);
const T& at(const key_type& x) const;

Also instead of a string literal you are using a multibyte character literal in this statement

 std::cout << SupportedPorts::supported_ports['COM1'];

Write

 std::cout << SupportedPorts::supported_ports.at( "COM1" );

Here is a demonstrative program.

#include <iostream>
#include <string>
#include <map>

int main()
{
const std::map<std::string, std::string> supported_ports =
{
{ "COM1", "ttySO1" }, { "COM2", "ttySO2" }, { "USB", "ttyUSB0" }
};

std::cout << supported_ports.at( "COM1" ) << '\n';

return 0;
}

The program output is

ttySO1

C++ map access discards qualifiers (const)

std::map's operator [] is not declared as const, and cannot be due to its behavior:

T& operator[] (const Key& key)

Returns a reference to the value that is mapped to a key equivalent to key, performing insertion if such key does not already exist.

As a result, your function cannot be declared const, and use the map's operator[].

std::map's find() function allows you to look up a key without modifying the map.

find() returns an iterator, or const_iterator to an std::pair containing both the key (.first) and the value (.second).

In C++11, you could also use at() for std::map. If element doesn't exist the function throws a std::out_of_range exception, in contrast to operator [].

using operator [] with a map in a const method

Use map's .find member function to do the search.

auto it = mymap.find("a");

if (it != mymap.end())
// it->first = key, it->second = mapped value.

Using operator[] instead of find won't make the search work any better. Either the keys match (in which case find will work just fine) or else they don't (in which case [] attempts to insert a new node with that key, which will be associated with a value-initialized value--an empty string in this case.

It's that latter behavior (inserting the new node) that means there's no const version of operator[].

Yes, it would have been possible to define operator[] in a way that worked with a const container, such as throwing an exception when/if the requested key wasn't present--but it's not defined to work that way now, and probably won't be any time soon either.

can't I use map [ ] operator with const function keyword?

The reason is because operator[] isn't const? I know that a const function can call only other const function.

Yes; operator[] is specified to create a new default-constructed element if the key doesn't exist, and this wouldn't be sensible on a const map, thus it's not marked as const.

Of course you could specify the const version to throw an exception (as at does) or - I don't know - call terminate if the key isn't found, but alas the standard doesn't say that. You'll either have to use at or (ugh) find.

C++, accessing std::map element via const reference

std::map::operator[] is not const, because it inserts an element if one does not already exist. In c++11, you can use std::map::at() instead:

myObj.someMap.at(0)

Otherwise, you can check whether the element exists first using std::map::find,

if (myObj.find(0) != myObj.end())
{
// element with key 0 exists in map
} else
{
// do something else.
}

How to add to std::map an object with constant field?

Use map::emplace to construct A in-place:

myMap.emplace("Hello", 3);

Demo.

If the key doesn't exist in a map, then assignment means "add pair
[key, value] to the map". But if the key exists, then replace the
value.

As @Serge Ballesta commented, when the key already exists, you need to erase the node from the map and emplace a new node:

const char* key = "Hello";
const int value = 3;
const auto it = myMap.find(key);
if (it != myMap.end())
myMap.erase(it);
myMap.emplace(key, value);

can't access const static std::map enum struct

operator[] is not const for a std::map.

Use at instead.

Before C++11 :

If you are not using C++11, you have to use find which has a const version.



Related Topics



Leave a reply



Submit