【问题标题】:Return type deduction of lambda expressions of if-else statementsif-else 语句的 lambda 表达式的返回类型推导
【发布时间】:2018-05-27 17:34:04
【问题描述】:

我正在阅读 C++ 入门第 5 版,第 10 章(lambdas 表达式),这是一个旨在将向量中的负值替换为绝对值的程序。

transform(vi.begin(), vi.end(), vi.begin(),
      [](int i) { if (i < 0) return -i; else return i; });

作者说:

此代码无法编译,因为 lambda 将返回类型推断为 void,但我们返回了一个值,为了解决这个问题,我们必须使用尾随返回类型。

但是当我在 Windows 上使用 GNU GCC 编译器编译这段代码时,它运行良好。

作者还说:

这个版本编译是因为我们不需要指定返回类型, 因为可以从条件的类型推断出该类型 运算符。

transform(vi.begin(), vi.end(), vi.begin(),
          [](int i) { return i < 0 ? -i : i; });

所以,我的问题是:

  • 为什么在第一个版本中,lambda 将返回类型推断为 void,为什么 GNU GCC 编译器接受这个。*(我认为这可能是因为优化)。?
  • 为什么在第二个版本中,返回类型可以从条件运算符的类型中推断出来?

【问题讨论】:

  • lambda使用返回的表达式来推导返回类型,所以不可能从return &lt;something&gt;推导出void...这本书有错误。
  • [](int i) { if (i &lt; 0) return -i; else return i; } 在 C++14 中完全没问题。
  • 书中所写的内容适用于 C++11,但在 C++14 中得到了改进,允许多个 return 语句(只要返回的类型匹配)。
  • 这是 C++ 有趣的时代。在相对较短的时间内添加和更新了许多新功能,因此您的阅读材料必须是最新的,或者您必须确保您的编译器是根据阅读材料的任何标准修订版的规则构建的写信给地址。
  • @DietmarKühl:但是相同的代码在 C++11 上也能正常工作?!!!这是否意味着书中有错误?

标签: c++ if-statement lambda conditional-operator


【解决方案1】:

来自lambda

...闭包的operator()的返回类型是根据 以下规则:

  • 如果主体只包含一个带有 表达式,返回类型是返回表达式的类型 (在左值到右值、数组到指针或函数到指针之后 隐式转换);否则,返回类型为 void。 (直到 C++14)

  • 返回类型是从返回语句推导出来的,就像函数一样 其返回类型声明为 auto。 (C++14 起)

所以作者只是描述了C++14之前的情况,因为C++14代码完美运行。

【讨论】:

  • 谢谢,我用的是C++14编译器,这才是真正的原因。
  • @StephaneWamba:我被困在同一点上。但是 OP 的代码甚至可以在 C++11 上运行。那么作者错了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
  • 2021-08-31
  • 2023-02-21
  • 1970-01-01
  • 2019-09-19
  • 1970-01-01
相关资源
最近更新 更多