Stl Map Containing References Does Not Compile

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 because it = 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



Leave a reply



Submit