【问题标题】:C++ sugar syntax for if (!result) return false;if (!result) 的 C++ 糖语法 return false;
【发布时间】:2014-01-20 15:19:46
【问题描述】:

在重构一些代码时,我经常会遇到这种情况:

bool highLevelFunc foo()
{
  // ...
  bool result = LesserLevelFunc();
    if (!result) return false;
  // ... Keep having fun if we didn't return
}

有没有什么办法可以让它更性感一点,不那么冗长?当然没有任何开销或陷阱。

我能想到一个宏

#define FORWARD_IF_FALSE(r) if (!r) return r;

bool highLevelFunc foo()
{
  // ...
  FORWARD_IF_FALSE(LesserLevelFunc());
  // ...
}

还有什么更好的,即没有预处理器宏?

【问题讨论】:

  • @MitchWheat 他只想在函数失败时退出函数。如果不是假的,他想继续。
  • @MitchWheat 在原始示例中,真实条件不会“返回”。
  • 很难说没有看到更多的代码...
  • @MitchWheat 我认为这三个点会很有意义。当然,我只想在子函数失败时返回:)
  • 您的FORWARD_IF_FALSE 计算两次LesserLevelFunc(如果为假)。它错过了r周围的括号。

标签: c++ syntactic-sugar


【解决方案1】:

对我来说,“可读”的代码很性感。我发现原始代码比您的建议更具可读性,因为原始代码使用标准 C++ 语法,而后者使用了我必须去查找的宏。

如果你想更明确一点,你可以说if (result == false)(或者更好的是,if (false == result) 以防止可能的赋值作为比较错误)但理解! 运算符是我的一个相当合理的期望意见。

也就是说,没有理由将返回值分配给临时变量;你可以简单地说:

if (!LesserLevelFunc()) return false;

这对我来说非常易读。

编辑:您还可以考虑使用异常而不是返回值来传达故障。如果LesserLevelFunc() 抛出异常,您不需要在highLevelFunc() 中编写任何特殊代码来检查是否成功。异常将通过调用者向上传播到最近的匹配 catch 块。

【讨论】:

  • 是的,在线检查/退货是要走的路。我同意例外情况,但不一定总是实用。
【解决方案2】:

因为如果LesserLevelFunc 返回 true,您可能会继续,我建议保持与现在非常接近的状态:

if (!LesserLevelFunc())
    return false;

【讨论】:

    【解决方案3】:

    首先介绍您使代码不安全的宏。而且你的宏是无效的。

    否定运算符后面的表达式用括号括起来。

    #define FORWARD_IF_FALSE(r) if (!( r ) ) return r;
    

    其次,宏调用 r 两次。有时两次调用一个函数并不等同于一次调用同一个函数。例如,该函数可能有一些副作用或在每次调用该函数时打开/关闭的内部标志。

    所以我会保持代码不变而不引入宏,因为宏不等同于原始代码的语义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-02
      • 2017-02-05
      • 2018-05-16
      • 1970-01-01
      • 1970-01-01
      • 2011-09-01
      • 2010-09-25
      相关资源
      最近更新 更多