I have this function that returns the location of a robot (which is just a [row][col] pair of indices from a matrix):
std::pair<int, int> World::getRobotLocation(char robot_name){
auto const & location = robots.find(robot_name);
if (location == robots.end()) {
std::cout << "Robot " << robot_name << " does not exist." << std::endl;
}
return location->second;
}
Below, I am trying to implement the move()
function, which takes in the robot name, location and which direction to move and updates the position accordingly:
std::string move(char robot, char direction) {
// Get robot and its location
std::pair<int, int> robot_location = std::pair<int, int> World::getRobotLocation(robot);
// Get direction to move from user
// if L, map_[row 1][col]
// if D, map_[row][col 1]
// if R, map_[row-1][col]
// if U, map_[row][col 1]
// According to user input, update the robot's location
if (direction == 'L') {
robot_location = robot_location[ 1][]
}
else if (direction == 'D') {
robot_location = robot_location[][-1]
}
else if (direction == 'R') {
robot_location = robot_location[-1][]
}
else {
robot_location = robot_location[][ 1]
}
}
In my variable robot_location
, I am saving the location of that particular robot. How can I access the values of this std::pair<int, int>
to be able to update them?
CodePudding user response:
I think you want something like this:
if (direction == 'L') {
robot_location.first = 1;
}
else if (direction == 'D') {
robot_location.second -= 1;
}
// ...etc (you get the idea)
first
and second
are the names of the two elements in a std::pair
(that's also why the return value of robots.find(...)
dereferences to something that has first
and second
- that's a std::pair
of the key and value types of the map).
Bear in mind that getRobotLocation
, as it's currently written, will return a copy of the std::pair
of coordinates, not a reference to the original coordinates inside the map. Therefore, just updating that std::pair
won't be enough on its own. You'll need to either save the value back into the robots
map, or change what getRobotLocation
returns (see @Goswin and @Ted's comments).
CodePudding user response:
Your first function has a bug. It reports when a robot is not found, but still dereferences the end iterator, which causes undefined behavior. Instead, you should return a pointer, which is conditionally null:
// Returns null if the robot is not found:
std::pair<int, int>*
World::getRobotLocation(char robot_name){
auto const location = robots.find(robot_name);
if (location == robots.end()) {
return nullptr;
}
return &location->second;
}
And in your other function, you check to see, if the pointer is not null, you update the value:
// Returns true if move happens,
// false otherwise.
bool
move(char robot, char direction) {
auto const robot_location = World::getRobotLocation(robot);
if (!robot_location) return false;
switch (direction) {
case 'L': {
robot_location->first;
} break;
case 'D': {
--robot_location->second;
} break;
case 'R': {
--robot_location->first;
} break;
default: {
robot_location->second;
} break;
}
return true;
}