当std::map::at超出范围时返回什么
What to return when a std::map::at goes out_of_range?
在游戏中,我希望搜索物品地图并返回位于棋盘特定方格上的物品。但是如果正方形是空的呢?(项目不存储在董事会结构中。为了这个问题的目的,不要介意那个。)我有下面的代码,但是我应该做什么来返回一个"空"引用?
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?
}
}
或者这是错误的方法,我应该使用find()
?
如果在程序中没有找到项不是错误条件,那么您应该不返回引用(因为引用不能为空)。相反,您应该返回一个(很可能是非拥有的)指针,并且在没有找到项目的情况下返回nullptr
:
Item* itemAt(int row, int col) const {
try {
return _items.at(make_pair(row, col));
} catch(out_of_range& e) {
return nullptr;
}
}
另一方面,如果找不到项是错误,那么你可以返回一个引用(当找到项时)并让异常传播当找不到项时-处理它的责任将属于你的代码中具有如何处理它的策略知识的部分:
Item& itemAt(int row, int col) const {
return *_items.at(make_pair(row, col));
}
在这种情况下,使用指针作为表示" 0或1个对象"的手段是有用的:
Item* itemAt(int row, int col) const {
try {
return _items.at(make_pair(row, col));
} catch(out_of_range& e) {
return nullptr;
}
}
然而,使用std::map::find()
可能是一种更快更干净的方法。
如果客户端代码请求不存在的项目是错误的,那么throw
将异常报告失败并返回Item&
。
如果不是错误,因为map
的value_type
已经是Item*
,将返回类型更改为Node*
并返回nullptr
,以指示请求位置的项不存在,并使用map::find()
。
为了避免Item&
返回类型已经存在的生命周期问题,可以考虑将value_type
更改为std::shared_ptr<Item>
。如果客户端代码有一个指向map
值的引用或原始指针,并且从map
中删除了该元素,那么客户端就留下了一个悬空指针/引用。切换到std::shared_ptr<Item>
可以避免这种情况。itemAt()
函数将返回一个std::shared_ptr<Item>
。这还有一个好处,即map
中的Item
不需要显式地为delete
d。
其实别人也有过同样的问题:
- 有人写
boost::optional
- 你可以返回一对指针和返回值
- 可以抛出异常
- 你可以返回一个空对象
- 程序中的布尔函数返回输入的范围无论如何都是无效的
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 从函数返回范围视图时,带有std::span:中间对象所有权的C++Ranges-v3
- 通过引用返回的变量的范围
- 私有在函数定义/实现的返回值范围内是什么意思 (c++)?
- 是否未定义将对函数范围变量的引用作为值返回
- 我们如何在范围消失时通过引用返回变量
- 指针范围问题和返回类中封装的指针向量内的指针引用
- 基于范围的 for 循环,用于包含C++中的指针的自定义链表,仅返回对象
- 为什么此范围基于语句返回一个数字太低的范围
- 范围分辨率运算符在类型:: var的情况下返回什么
- C++. 面试. 关于返回 int* 值问题的范围
- 为什么在.h中定义的私有结构需要.cpp文件中的返回类型中的范围
- 函数返回本地变量,尽管变量不超出范围,没有编译器问题,并且代码执行
- 优化的范围检查并返回值
- 为什么对象在作为指针传递时超出范围,而在返回时则不然
- 变量循环范围会导致返回局部变量的地址引用
- 从排序的数字数组中返回数字范围的最快方法是什么?
- 从参数和范围返回
- 为什么 gcc-4.9.2 不能支持 std::string.insert(迭代器,范围)返回迭代器