I am trying to compile the below code in VS2015. The first version of my std::map is compiling, but the seconds version does not compile. Please let me know what I am doing wrong here..
std::map<int, std::string> _p;
typedef std::pair<int, std::string> _q;
_p.insert(_q(0, "Football0"));
_p.insert(_q(1, "Football1"));
std::string str = _p[1]; //OK...compiles and executes, no error, str = "Football1" as expected
std::map<int, DataDictionary> _p1;
typedef std::pair<int, DataDictionary> _q1;
DataDictionary dd1;
dd1.i = 0;
dd1.version = "ver1";
_p1.insert(_q1(0, dd1));
DataDictionary dd2;
dd2.i = 0;
dd2.version = "ver2";
_p1.insert(_q1(1, dd2));
DataDictionary DD = _p1.find[1]; //error C3867: 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::find': non-standard syntax; use '&' to create a pointer to member
Even if I decide to change my std::map and use the following, I am getting the same error :
std::map<std::string, DataDictionary> _p1;
DataDictionary DD = _p1.find["1"]; //ERROR
I am trying to use map with the DataDictionary structure, and use _p1.find["1"] syntax to access the elements, as I am assuming that this approach will be faster than declaring iterator to the map, and then use find(). Please help. Thanks,
I am trying to use map with the DataDictionary structure, and use _p1.find["1"] syntax to access the elements
No, you are trying to use subscript operator on a member function:
find("1") would work.
find["1"] should not compile.
Consider using either _p1.find("1"), or _p1["1"]. The difference between them is that find returns a pair with a position in the map and a boolean flag an iterator (which may be past the end of the mapped sequence), and the subscript operator (["1"]) returns either a reference to the existing element, or it adds an element (if one is not found) and returns a reference to that.
To check if the map contains the key, use if(_p1.count("1")) instead.
I think you meant
_p1.find("1");
it returns an iterator to the found item.
use
std::map<std::string, DataDictionary>::iterator item = _p1.find("1");
or
in C++11 you can do
auto item = _p1.find("1");
Related
I have an unordered_map pointer in a structure since I need it in shared memory to access and modify as the program runs.
struct Umaps {std::unordered_map<int, int> *node_index;} ;
I then initialize the unordered_map, node_index, in another function.
Umapsptr->node_index = new std::unordered_map<int, int>();
Where Umapsptr is the pointer to the Umaps structure in my function. I then try to insert values to the unordered_map.
Umapsptr->node_index[5] = 10;
But I get this error and I don't know how to resolve it:
error: no match for ‘operator=’ (operand types are ‘std::unordered_map<int, int>’ and ‘int’)
Umapsptr->node_index[5] = 10;
What am I doing wrong? Any help would be incredibly appreciated.
Applying [] to a pointer does pointer arithmetic. You want to apply the [] to the pointed at object, so you need to explicitly dereference the pointer:
(*Umapsptr->node_index)[5] = 10;
If you know the key 5 is already in the map, you can use at instead:
Umapsptr->node_index->at(5) = 10;
but this will throw an exception if the key is not present. If you know the key is not present, you can use emplace:
Umapsptr->node_index->emplace(5, 10);
but this will do nothing if the key is already present with a different value.
I have a map<std::string, std::unique_ptr<Cls>> my_map. I would like to move out some value from this map, to have the following:
std::unique_ptr<Cls> cls = my_map.get_and_erase("some str");
erase doesn't return a value unfortunately. What is my best approach here?
Since C++17 you have std::map::extract:
// if the key exists in the map, it'll be deleted after this:
auto cls_node = my_map.extract("some str");
if(not cls_node.empty()) // cls_node.mapped() gives access to the mapped value
You can use the following algorithm:
Use find to get an iterator to the element.
Move from the element.
Erase using the iterator.
I made a map filled with vectors which looks like this:
std::map<int, std::vector<CClass*>> pointers = getMap();
And now I want to go through every slot of the map and also through every slot of the vector stored in the map.
This is how it goes through the map:
for (std::map<int, std::vector<CClass*>>::iterator it = pointers.begin(); it != pointers.end(); it++)
This works fine and it goes through every object just like I want it to.
But now I want to go through every slot in the vector and I tried it like this:
for (std::vector<CClass*>::iterator playerIt = it->second.begin(); playerIt != it->second.end(); playerIt++)
If I want to access the value stored in it the compiler gives me this error:
file.cpp(552) : error C2839: Ungültiger Rückgabetyp 'CClass **' für überladenen Operator '->'
Which means "invalid return-type 'CClass **' for overweight operator '->'
regards
You can use range-based for loops in C++11 to handle this more readably
for (auto& element : pointers)
{
for (auto& player : element.second)
{
// player will be a CClass* that you can use
std::string name = player->GetName(); // For example
}
}
playerIt is an iterator, not a pointer to a CClass. You need to dereference the iterator to get a pointer to CClass:
CClass * player = (*playerIt);
player->ClassMethod(...); // or whatever
playerIt is an iterator that returns a CClass*, but you dereference the iterator via operator->, so you need to dereference the pointer that is returned by the iterator.
So you are possibly saying playerIt->cclass_method() when you should be saying (*playerIt)->cclass_method();
Of course, storing shared_ptr<>, or unique_ptr objects in your vector might be better and easier to understand, along with using typedef to alias the vector<> part of the map.
Assume I have a nested map of type pointer. Then is there a single line statement to insert into the nested map,
map<int, map<int, int> >* nestedMap;
Currently I am doing this in 2 steps. First creating innermap and then insert into outer map as below,
nestedMap->insert(make_pair(int, map<int, int>)(int, innermap));
If the map is not pointer type, then i can insert easily like this,
nestedMap[int][int] = int;
Is there any simple ways for inserting into nested map of type pointer ?
thanks
Prabu
map::operator[] automatically creates the key/value pair if it doesn't exist.
(That's why it's not const!)
So you don't need to create the inner map manually.
If you want to avoid creating the pair automatically, then use map::find() or map::at().
I believe the simplest one-liner is:
(*nestedMap)[int][int] = int;
If i understand your question properly, you can actually use reference instead of pointer. You are not having issue with nested map, instead your outter map.
See below code, is what you want?
map<int, map<int, int> >* nestedMap = new map<int, map<int, int> >;
map<int, map<int, int> > &nestedMapAlais = *nestedMap;
nestedMapAlais[1][2] = 3;
access the operator[] via ->:
nestedMap->operator[](5)[6] = 7;
This is analogous to
nestedMap[5][6] = 7;
if nestedMap is not a pointer.
Note that in neither case do you have to explicitly insert a map.
I'm using Google's sparsehashmap, and trying to work out if a value was inserted or looked up. The following works, but obviously it's looking it up twice. How do I do it without the double lookup?
Element newElement = Element();
bool inserted = ((*map).insert(pair<const int64, Element>(key, newElement))).second;
Element element = (*(((*map).insert(pair<const int64, Element>(key, newElement))).first)).second;
if (inserted)
puts("INSERTED");
I can't check the contents of Element (it's a struct) as I want to differentiate between a default Element being found and newElement being inserted. I couldn't work out how to assign ((*map).insert(pair<const int64, Element>(key, newElement))) to a variable as it's of a template type that includes types private to the sparse_hash_map class.
Try this:
typedef sparse_hash_map<...>::iterator sh_iterator; //you already have this, haven't you?
std::pair<sh_iterator, bool> res = map->insert(std::make_pair(key, newElement));
if (res.second)
puts("INSERTED");
If, for whatever reason you don't like the std::make_pair function, you should consider a typedef for the pair type:
typedef pair<const int64, Element> map_pair;
Anyway, the return type of insert is pair<iterator, bool>, and AFAIK iterator is a public typedef of the class.
BTW, I don't get why you do the second insert... to get to the inserted element? Probably you should declare element as a reference. In my suggested code:
Element &element = res.first->second;
Naturally, if you were using C++11, you could simply do:
auto res = ...;