STL map containing references does not compile
It is illegal to store references in an stl container, because types must be copy constructible and assignable. References can not be assigned.
Exactly what operation causes the first error is implementation dependent, but I image that it is related to creating a reference and not assigning it immediately. The second error message looks like its actually related to building the map index.
If your type is small, you can copy it into the map, or if it is large consider using pointers instead, but remember that the container will not deallocate the objects for you, you'll have to do that explicitly yourself.
This SO question might be of interest to you.
Why Can't I store references in a `std::map` in C++?
They way I understand it, references are implemented as pointers under the hood. The reason why you can't store them in a map is purely semantic; you have to initialize a reference when it's created and you can't change it afterward anymore. This doesn't mesh with the way a map works.
C++ const std::map reference fails to compile
Yes you can't use operator[]
. Use find
, but note it returns const_iterator
instead of iterator
:
std::map<std::string, std::string>::const_iterator it;
it = map.find(name);
if(it != map.end()) {
std::string const& data = it->second;
// ...
}
It's like with pointers. You can't assign int const*
to int*
. Likewise, you can't assign const_iterator
to iterator
.
use of std::less in std::map does not compile
In the first program, you have a vexing parse. If the compiler can parse a declaration as either a variable or a function, it will choose to parse it as a function.
myMap
can be parsed as a function declaration.
It returns a std::map<int, int, std::less<int>>
.
It takes an argument of type std::less<int>()
, which is itself a function type that returns a std::less<int>
and takes no arguments. Note that you can't actually have a function type as an argument; the type is actually a pointer to a function that takes no arguments and returns a std::less<int>
.
In the second program, replacing ()
with {}
resolves the ambiguity. Now myMap
can no longer be a function declaration, and so it instead declares a variable of type std::map<int, int, std::less<int>>
.
C++: Is it possible to use a reference as the value in a map?
No. STL container value types need to be assignable. References are not assignable. (You cannot assign them a different object to reference.)
Can a reference type be used as the key type in an STL map
According to C++ Standard 23.1.2/7 key_type
should be assignable. Reference type is not.
Passing c++ map by reference and see changes after insert
map
and copyMap
are separate objects and so changing one won't affect other. Moreover, you're returning the map by value from the function passMapByReference
. Instead you could return the map by reference from passMapByReference
as shown below:
#include <iostream>
#include <map>
#include <string>
//------------------------v------->return by reference
std::map<std::string, int>& passMapByReference(std::map<std::string, int>& temp_map){
return temp_map;
}
void printMap(std::map<std::string, int>& temp_map ){
std::cout << temp_map.size() << std::endl;
}
int main()
{
std::map<std::string, int> map;
map["asd"] = 1;
map["dsa"] = 2;
printMap(map);
//copyMap is an lvalue reference to passMapByReference
std::map<std::string, int>& copyMap = passMapByReference(map);
printMap(copyMap);
map["ksdbj"] = 3;
map["askdnijabsd"] = 4;
printMap(map);
printMap(copyMap);//prints 4
}
Working demo
The output of the above program is:
2
2
4
4
Note
I noticed that you have used using namespace std;
and then created a map
with the name map
. This should be avoided as it creates confusion. For example, it becomes hard to see whether the map
you're referring to is a std::map
or the variable named map
. I would recommend using std::
to qualify the standard contianers instead of using using namespace std;
.
Refer to Why is "using namespace std;" considered bad practice?
std::map::iterator references non-existing object?
what Object does
it->second
reference? Is this an invalid reference becauseit = myMap.end()
?
Indeed. myMap.end()
is a valid iterator but it must not be dereferenced. it->second
attempts to do exactly that and causes undefined behaviour.
map<int,MyClass>
does not create an instance of MyClass.
True, but irrelevant. myMap.end()
will always – no matter the content of myMap
– contain a reference to a “one past end” iterator which must never be dereferenced.
Related Topics
What Happens When C++ Reference Leaves Its Scope
How to Statically-Initialize a Dynamically-Allocated Array in C++
Video Processing with Opencv in iOS Swift Project
Threadsafe Vector Class for C++
Why C++ Doesn't Support Named Parameter
Exporting Static Data in a Dll
Does Gcc Inline C++ Functions Without the 'Inline' Keyword
How Concatenate a String and a Const Char
How to Call a Cmake Function from Add_Custom_Target/Command
Best Way to for C++ Types to Self Register in a List
Win32 C/C++ Load Image from Memory Buffer
A Class-Key Must Be Declared When Declaring a Friend
Is It Legal to Cast a Pointer to Array Reference Using Static_Cast in C++