【问题标题】:Why can std::function be constructed with a lambda with a different return type?为什么 std::function 可以用具有不同返回类型的 lambda 构造?
【发布时间】:2017-01-09 13:56:10
【问题描述】:

以下compiles fine

#include <functional>

int main()
{
    std::function<const int&()> f = []() -> int {return 1;};
    const int& r = f(); // r is a dangling reference
    return 0;
}

为什么可以将具有const int&amp; 返回类型的std::function 设置为具有int 返回类型的lambda?允许这种类型的演员在没有任何警告的情况下隐式发生是一个陷阱,恕我直言。

【问题讨论】:

  • 因为一个 const 引用可以绑定到一个临时的。 std::function 本身没有问题。您将获得与旧功能相同的净效果。 该语言的那部分不会很快消失。
  • 但是返回的临时的析构函数被调用。在这里演示melpon.org/wandbox/permlink/nSzeMfQM0Jpz9xbW
  • 然后呢? C++ 从来没有保护你免于击中自己的脚。编译器可能很好并发出警告,但从纯 C++ 的角度来看,这仍然是一个有效的程序。这会一直存在,因为在某些情况下将临时对象绑定到引用可以延长临时对象的生命周期。而且那个非常有用。
  • 不过,这并不能真正回答问题。 const 引用可以绑定到临时对象的事实并不能直接得出具有 const 引用返回类型的 std::function 可以从具有值返回类型的 lambda 构造。
  • 但确实如此。因为std::function 旨在允许发生任何有效的转换。对于程序员应该注意的极端情况,过度复杂化是毫无意义的 IMO。

标签: c++ lambda std-function


【解决方案1】:

您可以使用任何可使用相关参数调用的对象构造std::function,并且其返回值可隐式转换为std::function 返回值。 int 可以隐式转换为const int&amp;,因此符合规则。

编译器可以随意对此发出警告,但对于特别极端的极端情况来说,这似乎需要做很多工作。

【讨论】:

  • 谢谢。它实际上不是那种角落-y,因为很容易(至少对我来说)错误地假设返回 const 引用的 lambda 的推导返回类型也是 const 引用,这是错误的;它只是一个值。所以这是我实际上遇到的一个错误,因为对 lambda 的返回类型推导不够了解(如果你很好奇,请参阅stackoverflow.com/questions/41534031/…
  • 警告引用返回绑定到一个临时的似乎很值得,实际上在大多数主要编译器中都实现了。这里的问题是损坏的返回发生在抑制警告的系统标题中。此外,还有一个LWG issue 要求对std::function 进行调整,以使 OP 的代码无法编译。
猜你喜欢
  • 2017-10-06
  • 2020-11-26
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
相关资源
最近更新 更多