【问题标题】:What should a function return that can fail?一个可能失败的函数应该返回什么?
【发布时间】:2018-06-03 13:42:41
【问题描述】:

我的问题有点含糊,至少部分是故意的。我正在寻找有关界面设计、未来扩展和易于测试的界面的早期建议,而不是关于确切代码的太多建议。虽然,如果它是特别适用于 C++(17) 的解决方案/建议,那就完美了。

我有一个模拟可以解决一个困难的组合问题。模拟逐步传播到解决方案。但有时,一个步骤是一个死胡同(或出现这样的情况)。例如,在下面的伪代码中,while 循环通过向其提供片段来传播模拟。可能存在无法使用“片段”来传播模拟的情况。例如。它太贵了,它根本不适合,或者出于某种原因。失败是一种正常的行为,可能会出现没有理由中止。

while(!allNotHandledPieced.empty())
{
  auto nextPiece = allNotHandledPieces.back();
  allNotHandledPieces.pop_back();
  auto status = simulation.propagate(nextPiece);
  if(status == 0)
    next; // ok
  else if (status == 1)
    dropPieceDueToTooBadStatus();
}

实际上,对于“模拟”而言,失败的原因并不重要。状态仍然有效,使用另一块没有问题,它可以继续。但后来,我可能需要知道为什么“传播”方法失败了。那么在失败时有一个有意义的返回值可能是有意义的。

有没有返回“失败”的好方法?对于这种情况,是否有最佳做法

【问题讨论】:

  • 你听说过execptions吗?
  • std::optional 在 C++17 或 boost::optional
  • throw关键字的使用。
  • 这正是异常旨在处理的那种异常情况。 stackoverflow.com/questions/8480640/how-to-throw-a-c-exception
  • 正在进行异常处理。另一个是返回一个Result 对象,它可能包含有关结果的所有信息。如果一切顺利,它可以包含结果,如果失败,它可以包含原因。 C++17 有[[nodiscard]],所以很难忘记检查结果。

标签: c++ error-handling return c++17


【解决方案1】:

据我所知,似乎例外或“返回”都不适合您的情况。在您的问题中,您谈论“返回结果”,但您的特定代码示例/用例表明,如果使用“坏块”,算法不应停止或中断。异常和从函数“返回”都会导致更复杂的控制流,并且在某些情况下,会导致更复杂的状态处理,具体取决于您处理异常的方式。

如果您选择异常路线,我建议您在system_error 之后建模您的“报告”类。

如果您选择非控制流路由,我建议将错误代码和有关该片段的其他元数据(如果片段本身太昂贵而无法复制)推送到另一个可以使用它的数据结构中。

你选择做什么取决于坏的部分是否需要立即采取行动。如果不是,则异常不是要走的路,因为这意味着它需要在某个时候进行处理。

【讨论】:

    猜你喜欢
    • 2011-07-06
    • 2012-12-04
    • 2013-06-08
    • 2019-07-08
    • 2023-04-01
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多