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
Problem Sorting Using Member Function as Comparator
C++11 Reverse Range-Based For-Loop
Are Members of a C++ Struct Initialized to 0 by Default
Why Are Arrays of References Illegal
How to Compile a 64-Bit Application Using Visual C++ 2010 Express
Why Aren't Pointers Initialized With Null by Default
Error Lnk2019: Unresolved External Symbol _Winmain@16 Referenced in Function _Tmaincrtstartup
What Does It Mean to "Odr-Use" Something
Explicit Specialization in Non-Namespace Scope
Why Does Const Imply Internal Linkage in C++, When It Doesn't in C
Why Vector≪Bool≫::Reference Doesn't Return Reference to Bool
Propagating 'Typedef' from Based to Derived Class For 'Template'
Is There a Limit on Number of Open Files in Windows
Why Does Stringstream ≫≫ Change Value of Target on Failure
C++, What Does the Colon After a Constructor Mean
How to Install the Raspberry Pi Cross Compiler on My Linux Host Machine