我什么时候应该使用std::expected异常?什么时候应该使用异常?以这个函数为例:
int parse_int(std::string_view str) {
if (str.empty()) {
throw std::invalid_argument("string must not be empty");
}
/* ... */
if (/* result too large */) {
throw std::out_of_range("value exceeds maximum for int");
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我想在使用此函数时区分不同的错误,因此抛出不同类型的异常很有用。但是,我也可以这样做std::expected:
enum class parse_error {
empty_string,
invalid_format,
out_of_range
};
std::expected<int, parse_error> parse_int(std::string_view str) noexcept {
if (str.empty()) {
return std::unexpected(parse_error::empty_string);
}
/* ... */
if (/* result too large */) {
return std::unexpected(parse_error::out_of_range);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
是否有任何理由使用std::expected异常(性能、代码大小、编译速度、ABI),或者只是风格偏好?
我正在编写一个基于MVVM的VB.NET Winforms项目(使用Winforms绑定).我的直觉是永远不允许域实体处于无效状态.这要求我在构造函数中为新实体和现有实体的每个setter中进行验证检查:
Public Class Product
Public Sub New(ProductID as Integer, Name as String)
If ProductID > 0 AndAlso Name.Length > 5 Then
_ProductID = ProductID
_Name = Name
Else
Throw New InvalidProductException
End If
End Sub
Private _ProductID as Integer
Public Property ProductID as Integer
Set(value as String)
If value > 0 then
_ProductID = value
Else
Throw New InvalidProductException
End If
End Set
End Property
'Same principle as above for Name setter.
End Class
Run Code Online (Sandbox Code Playgroud)
然后我跑过Data Annotations,看起来很漂亮.我注意到大多数使用数据注释的人允许域实体暂时变为无效,然后在稍后通过调用Validate.ValidateObject来验证实体.此时,实体无效,原始状态已丢失,除非您有其他机制将其回滚.
两个问题:
1)您是否允许域名实体暂时无效?
2)根据您对#1的回答,您使用哪些技术来验证实体?
在我看来,如果你有一些像这样的C++代码:
int f()
{
try {
if( do_it() != success ) {
throw do_it_failure();
}
} catch( const std::exception &e ) {
show_error( e.what() );
}
}
Run Code Online (Sandbox Code Playgroud)
C++编译器应该能够优化throw并捕获几乎简单的goto.
但是,从我查看反汇编和单步执行代码的经验来看,编译器总是跳过非常混乱的异常处理库.
他们为什么这样做?是否存在一些阻止优化的语言要求?如果它是:
int f()
{
try { throw std::runtime_error("Boo!"); }
catch ( const std::exception &e ) { std::cout << e.what() << std::endl; }
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器不只是重写为
int f()
{
std::cout << "Boo!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)