If std::optional
's value()
成员函数被调用时optional
没有初始化实际值,astd::bad_optional_access
被抛出。因为它直接源自std::exception
,你需要catch (std::bad_optional_access const&)
or catch (std::exception const&)
用于处理异常。然而,这两种选择对我来说似乎都很悲伤:
-
std::exception
捕获每一个异常
-
std::bad_optional_access
公开实施细节。考虑以下示例:
Placement Item::get_placement() const {
// throws if the item cannot be equipped
return this->placement_optional.value();
}
void Unit::equip_item(Item acquisition) {
// lets the exception go further if it occurs
this->body[acquisition.get_placement()] = acquisition;
}
// somewhere far away:
try {
unit.equip_item(item);
} catch (std::bad_optional_access const& exception) { // what is this??
inform_client(exception.what());
}
因此,要捕获异常,您需要充分了解std::optional
in the Item
的实施,导致了一系列已知问题。我也不想抓住并重新包装std::bad_optional_access
因为(对我来说)例外的关键部分是在需要之前忽略它们的可能性。这就是我认为正确的方法:
std::exception
<- std::logic_error
<- std::wrong_state (doesn't really exist)
<- std::bad_optional_access (isn't really here)
因此,“遥远”的例子可以写成这样:
try {
unit.equip_item(item);
} catch (std::wrong_state const& exception) { // no implementation details
inform_client(exception.what());
}
Finally,
- Why is
std::bad_optional_access
设计得像这样吗?
- 我对异常的感觉正确吗?我的意思是,它们是为了这种用途而引入的吗?
Note: boost::bad_optional_access
源自于std::logic_error
. Nice!
注2:我知道catch (...)
并投掷除以下类型以外的物体std::exception
家庭。为了简洁(和理智),它们被省略。
更新:不幸的是,我不能接受两个答案,所以:如果你对这个话题感兴趣,你可以阅读胡作典的回答和他们的评论。