相关疑难解决方法(0)

何时使用 std::expected 而不是异常

我什么时候应该使用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),或者只是风格偏好?

c++ error-handling exception c++23 std-expected

8
推荐指数
0
解决办法
697
查看次数

域对象是否应该暂时无效,该决定如何影响验证技术?

我正在编写一个基于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的回答,您使用哪些技术来验证实体?

.net validation domain-driven-design

7
推荐指数
3
解决办法
1546
查看次数

C++异常抛出/捕获优化

在我看来,如果你有一些像这样的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)

c++ optimization exception

3
推荐指数
3
解决办法
958
查看次数