In a game I would like to search a map of items and return the one located on a particular square of the board. But what if the square is empty? (The items are not stored in the board structure. Never mind about that for the purposes of this question.) I have the code below, but what should I do to return an "empty" reference?
map<pair<int, int>, Item*> _items;
Item& itemAt(int row, int col) const {
try {
return *_items.at(make_pair(row, col));
} catch(out_of_range& e) {
return // what goes here?
}
}
Or is this the wrong approach and I should just use find()
?
The C++ function std::map::at() returns a reference to the mapped value associated with key k.
Return Value: The function returns an iterator or a constant iterator which refers to the position where the key is present in the map. If the key is not present in the map container, it returns an iterator or a constant iterator which refers to map. end().
Defines a type of object to be thrown as exception. It reports errors that are consequence of attempt to access elements out of defined range.
C++ map at() function is used to access the elements in the map with the given key value. It throws an exception out_of _range, if the accessed key is not present in the map.
If not finding an item is not an error condition in your program, then you should not return a reference (since references cannot be null). Rather, you should return a (non-owning, most likely) pointer, and return nullptr
in case the item was not found:
Item* itemAt(int row, int col) const {
try {
return _items.at(make_pair(row, col));
} catch(out_of_range& e) {
return nullptr;
}
}
On the other hand, if not finding an item is an error, then you can return a reference (when the item is found) and let the exception propagate when the item is not found - the responsibility of handling it would belong to the part of your code that has strategic knowledge on how to handle it:
Item& itemAt(int row, int col) const {
return *_items.at(make_pair(row, col));
}
In this case, using a pointer as a means to represent "zero or one object" is useful:
Item* itemAt(int row, int col) const {
try {
return _items.at(make_pair(row, col));
} catch(out_of_range& e) {
return nullptr;
}
}
However, using std::map::find()
is probably a faster and cleaner approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With