Pair Value Reading Errors C++ - c++

I am getting the compiler error:
error: request for member 'first' in 'list.std::map::operator[],
std::less, std::allocator > > >((* &0.0)).std::pair::second', which is
of non-class type 'int' int closestX = list[0].second.first;
when trying to read data from a map called list defined and with iterator as:
map<double, pair<int, int>> list;
map<double, pair<int, int>>::iterator it = list.begin();
Members in list are inserted with:
list.insert(it, pair<double, pair<int, int>>(findDistance(posr,posc,j, i), pair<int, int>(j, i)));
I am reading the value from the map using:
int closestX = list[0].second.first;
int closestY = list[0].second.second;
The error seems to indicate that the return type of list[0].second.first is non class type int, but that return type matches perfectly with the value type of closestX, and I have now hit a wall. Assume list[0] is initialized and holds a valid value.

list[0] is already of value type pair<int, int>, not of the iterator type. So you could write
int closestX = list[0].first;
int closestY = list[0].second;

The error seems to indicate that the return type of list[0].second.first is non class type int
No, the error message is telling that list[0].second is not class type so you can not perform .first on it.
Note that std::map::operator[] will return the mapped_type.
Returns a reference to the value that is mapped to a key equivalent to key.
list => map<double, pair<int, int>>
list[0] => pair<int, int>
list[0].second => int
list[0].second.first => failed

Related

How to get pair from a map using key in C++

I have the following map:
std::map<char, std::pair<int, int> > robots;
I am using this function to populate the map given the input meets certain conditions:
bool World::addRobot(int row, int col, char robot_name) {
// This if block checks if the desired location is a valid 1 and keeps a track of all the robots already in the grid
if (map_[row][col] == '1' && robots.find(robot_name) == robots.end()){
map_[row][col] = robot_name;
robots.insert(make_pair(robot_name, std::make_pair(row, col)));
}
else{std::cout << "Invalid input" << std::endl;}
return true;
}
Each robot name, which is just a single char, is saved with a pair of its location, which are just row/col coordinates. In the following function, I want to be able to retrieve & ethe location pairs given the robot name:
std::pair<int, int> World::getRobot(char robot_name) {
std::pair<int, int> location = robots.find(robot_name);
return location;
}
But the name location is redlines with the following error message:
No viable conversion from 'std::map<char, std::pair<int, int>>::iterator' (aka '_Rb_tree_iterator<std::pair<const char, std::pair<int, int>>>') to 'std::pair<int, int>'
Where am I going wrong? How can I return the coordinate pairs from just the robot name?
An iterator for a map "points to" a std::pair<const KEY, VALUE>.
For your map, the KEY is char and the VALUE is std::pair<int, int>
So in your code, instead of:
std::pair<int, int> location = robots.find(robot_name);
you need to:
std::pair<int, int> location = robots.find(robot_name)->second;
Also, you need to check and see if the call to find fails to find the key you want. In that case the iterator will be equal to robots.end, and you'll have to deal with that:
const auto it = robots.find(robot_name);
if (it != robots.end()) {
return it->second;
} else {
// Not found, do something else
}
std::map::find returns a map iterator which is a "logical pointer" to a std::pair of key and value of the element in the map (not only the value).
The second member of this pair is the value that you seek to return from getRobot (which is by itself a pair of ints).
Fixed version:
std::pair<int, int> World::getRobot(char robot_name)
{
auto it = robots.find(robot_name);
if (it == robots.end())
{
return std::pair<int, int>(0, 0); // return some default value
}
return it->second;
}
2 additional notes:
I used auto which is very convenient when using iterators (instead of specifying the long iterator type).
I added a check whether the key is in the map. If not - return some default value. You can change the default value, or change the method prototype to return an error status in this case.

How do we understand the Iterator for a set<pair<int,int>>?

So I have declared a set which will hold a pair of integers.
What is temp ? Does it mean that temp will point to a pair<int,int> ?
set<pair<int, int>> myset;
pair<int, int> temp = *(myset.begin());
How is the code below different from the code above? Can I please have a definition of what exactly these codes are doing.
pair<int, int>::iterator temp;
temp = *(myset.begin());
In this code:
set<pair<int, int>> myset;
pair<int, int> temp = *(myset.begin());
the variable temp is a pair, holding two int's.
myset.begin() returns an iterator, pointing to the first element in the set of pair's named myset. It gets dereferenced by * and the value (the pair) gets copied into temp.
In this code:
pair<int, int>::iterator temp;
temp = *(myset.begin());
the variable temp is first declared as an iterator for a pair<int, int> and then the code tries to copy the value of a pair<int, int> into it. This will not compile.
At the second example you are trying to assign a std::pair<int, int> to an iterator. This does not work, as iterators only point at data, and do not own the data.
pair<int, int>::
iterator temp = *(myset.begin());
// ^ gives iterator at the start of set, pointing to first el.
// ^ dereferences iterator, gives `std::pair<int, int>&`
// ^ `std::pair<int, int> is assigned to non-reference, and therefore
// forced to copy.
// ^ temp is an iterator to an element (iterators don't own elements,
// only point to them). You can't initialize an iterator with data.

Adding pair in set

I am trying to insert pair of int and string in my set. What i am trying to do is implement a hash map using sets, I am storing the number and its corresponding string using store function and then retrieving the string using retrieve. Please suggest what is the problem and is there any way it can be done more efficiently. The error is in store function. I have not written main function as its just taking input and calling the functions.
typedef pair<int, string> pairs;
pairs p;
set<pairs> s;
set<pairs>::iterator it;
int i=0;
void store(int num,string s)
{
p[i].first=num; //error is while I am using the pair to store the string
p[i].second=s;
s.insert(p[i]);
i++;
}
string retrieve(int num)
{
for(it=s.begin();it!=s.end();++it)
{
pairs m = *it;
if(m.first==num)
{
return m.second;
}
}
}
My error:
error: no match for ‘operator[]’ (operand types are ‘pairs {aka std::pair<int, std::basic_string<char> >}’ and ‘int’)
p[i].first=num;
pairs is a type alias for pair<int, string>. std::pair does not have an operator[] overload.
Assuming you want pairs to represent a collection of pairs, you need to make your pairs a container (e.g. a vector or an array).
As Martin Bonner noted in the comment, the symbol s inside store refers to the string s parameter. Change it to avoid clashing with set s's identifier.
typedef pair<int, string> pairs[100];
pairs p;
void store(int num, string str)
{
p[i].first=num;
p[i].second=str;
s.insert(p[i]);
i++;
}

Getting error when accessing .first or .second in map <std::pair<float,float>, std::vector<float> >

So I am trying to iterate over a map who's key is a pair of floats, and its' values are vectors of floats. I was following different examples on stackoverflow on how to access key and value, but I am having problems of using .first or .second . Here is my setup.
typedef std::pair<float, float> XYPair;
typedef std::map<XYPair, std::vector<float> > VectorsMap;
VectorsMap points;
VectorsMap::iterator iter;
//some function that spits back a VectorsMap map.
points = fileParser.parseFile();
//iterate over all vectors
for (iter = points.begin(); iter != points.end(); iter++) {
XYPair key = iter.first;
}
Here is the error:
myMain.cpp: In function âint main(int, char**)â:
myMain.cpp:21: error: âstruct std::_Rb_tree_iterator<std::pair<const std::pair<float, float>, std::vector<float, std::allocator<float> > > >â has no member named âsecondâ
make: *** [myMain.o] Error 1
I have not used an iterator before so please cut me some slack.
An iterator has a similar interface to a pointer. If you have a pointer p to a pair, you'd have to write p->first and p->second, not p.first and p.second.
Here, you'll want to write XYPair key = iter->first;

Map iterators traversal technique

I was having problem declaring an iterator to traverse through a map and find values. I'm getting a error of "expected initializer before 'fibiter'".
map <int, int> fibHash;
int memoized_fib(int n)
{
map <int, int> iterator fibiter = fibHash.find(n); //ERROR HERE
if(fibiter != fibHash.end())
return *fibiter;
int fib_val;
if(n <= 1)
fib_val = 1;
else
fib_val = memoized_fib(n - 1) + memoized_fib(n - 2);
fibHash[n] = fib_val;
return fib_val;
}
int main()
[..]
You forgot to use the scope resolution operator, ::. The compiler thinks you declared a map<int, int> named iterator, and therefore gets mighty confused when it finds fibiter.
map<int, int>::iterator fibiter
is what you want
map <int, int> iterator → map <int, int>::iterator
iterator is a typedef defined within the class "map".
You can look that up on the implementation of the standard library shipped with GCC 4.6.3 in <bits/stl_map.h> line 139, you have:
typedef typename _Rep_type::iterator iterator;
As the typedef belongs to the definition of the class, you should add the ":" so that the compiler knows where to find it.