声明以下函数noexcept
是否安全,即使v.at(idx)
理论上可以抛出out_of_range
异常,但实际上不是由于边界检查?
int get_value_or_default(const std::vector<int>& v, size_t idx) noexcept {
if (idx >= v.size()) {
return -1;
}
return v.at(idx);
}
答案 0 :(得分:15)
你对&#34;安全&#34;?的定义是什么?如果您在标记为noexcept
或noexcept(true)
的函数中抛出异常,那么您的程序将被终止(标准15.4.9)
每当抛出异常并且搜索处理程序(15.3)遇到a的最外面的块时 函数具有不允许异常的异常规范,然后,
- 如果异常规范是动态异常规范,则函数std :: unexpected()是 叫(15.5.2),
- 否则,调用函数std :: terminate()(15.5.1)。
只要这是可以接受的那么你就没事了。如果你不能容忍程序终止,那就不安全。
答案 1 :(得分:9)
很安全。如果发生异常,声明函数noexcept
将导致程序立即终止(通过调用terminate()
)。只要没有抛出异常,一切都很好。
答案 2 :(得分:4)
我们没有完整的方案来确定确切该功能是否能够投掷。
您的假设是正确的:因为您正在执行std::vector::at
无论如何都要做的事情,在给定的上下文中不太可能是有害的。然而,一般来说,这样的函数可能成为无效因素的主体,因此可能会抛出异常。这些可能是线程,进程或信号,可能会将执行交错到可能修改std::vector
的代码,而这些代码无法安全处理,std::vector::at
也不能。
如果你想考虑这些可能性,你需要有类似
的东西int get_value_or_default(const std::vector<int>& v, size_t idx) noexcept
{
try { return v.at(idx); }
catch (std::out_of_range const& e) { return -1; }
}
答案 3 :(得分:2)
即使
v.at(idx)
理论上可以抛出out_of_range
异常,但实际上不是由于边界检查?
理论上,它不可能。
如果你从理论上思考这个函数,那么边界检查就是你必须考虑的关于整个函数理论的一部分,所以唯一的理论方法就是如果有一个条件idx >= v.size()
不是真的而且v.at(idx)
扔了。
所以在你的陈述中,它理论上可以抛出&#34;是错的。
(在实践中,如果你在使用at()
的实施过程中遇到错误,它可能会抛出,但是你遇到了更大的问题并且随着noexcept
的爆炸而导致你做得可能更好。)
答案 4 :(得分:0)
big-O组织中的某个人可能已经聪明地从std::vector<int>
派生了他的类,然后重载了size()和at()以满足他的喜好。然后在代码中的某个地方调用你的函数,但令每个人都惊讶的是程序终止而不是异常被高举。
确实很有用,但这不是关于std::vector<int>
......的问题,而是关于背后的编程实践。
不幸的是,你假设你的输入无法保证,这就是为什么不安全;至少在大型代码域中。