你可以定义
boost::assertion_failed(...)
和
BOOST_ENABLE_ASSERT_HANDLER
从中抛出异常
boost::optional
.
代码:
#include<boost/exception/to_string.hpp>
namespace boost{
void assertion_failed(char const* expr, char const* function, char const* file, long line){
throw std::runtime_error(std::string()
+ expr +
" from " + function +
" at " + file + ":" + boost::to_string(line)
);
}
}
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/optional.hpp>
#undef BOOST_ENABLE_ASSERT_HANDLER
int main(){
double d = *boost::optional<double>{}; // throws! (width fairly useful msg)
(void)d;
}
terminate called after throwing an instance of 'std::runtime_error'
what(): this->is_initialized() from reference_type boost::optional<double>::get() [T = double] at /usr/include/boost/optional/optional.hpp:992
其他参考资料:
http://boost.2283326.n4.nabble.com/optional-How-to-make-boost-optional-throw-if-trying-to-access-uninitialized-value-td2591333.html
笔记:
1) 它可能需要对
assertion_failed
总的来说是有用的。如果你想抛出不同类型的异常,除了在
断言失败
就我的口味而言,(也是):
namespace boost{
void assertion_failed(char const* expr, char const* function, char const* file, long line){
if(std::string("this->is_initialized()") == expr) throw std::domain_error("optional is not intialized");
throw std::runtime_error(std::string()
+ expr +
" from " + function +
" at " + file + ":" + boost::to_string(line)
);
}
}
assert
这不是一个好的选择。在我看来,这个词有很多用法
在不涉及函数返回的上下文中。
3) 现在有一个
std::experimental::optional
版本奇怪的是,他们决定在考虑价值时对这个问题持不可知论
*
(自
未经检查
但是
这个
.value()
会员可以投掷
std::experimental::bad_optional_access
例外。这是一个有趣的设计选择(加上这两种方式都没有)
断言
S我认为这是正确的。