【问题标题】:Is a lambda without capture list usually implemented as ordinary function? [closed]没有捕获列表的 lambda 通常实现为普通函数吗? [关闭]
【发布时间】:2018-05-22 08:45:23
【问题描述】:

这个问题源于另一个问题 Why isn't a lambda that captures variables by reference convertible to a function pointer? 。似乎带有捕获列表的 lambda 被实现为带有 operator () 的本地类。

据我所知,没有捕获列表的 lambda 可以转换为函数指针,看起来它只是一个普通的函数。更重要的是,将没有捕获列表的 lambda 与普通函数进行比较时,我找不到任何特别之处。

同时,我认为没有捕获列表的lambda作为普通函数没有必要不实现。

【问题讨论】:

  • " 我认为没有必要不实现没有捕获列表的 lambda 作为普通函数。"我经常使用 lambda,can 这样做感觉很舒服。编写一个独立的函数并获取地址只是更多的工作要做。并且它拆分了函数定义和使用,可以通过使用捕获更少的 lambda 来避免。所以我有必要使用它;)
  • 请使用not 使用random 代码markups。
  • 是指编译器还是程序员?
  • I think there is no necessity to not implement lambda without 三重否定!新纪录!
  • @PasserBy - 只有在有人检查时,它才必须具有唯一的类型。如果我们所做的只是将 lambdas 转换为函数指针,我们如何知道它们是否有不同的类型?无论如何,我的观点应该是你可以 convertible 到一个函数指针而不 being 一个函数。

标签: c++ c++11 lambda


【解决方案1】:

而且,将没有捕获列表的 lambda 与普通函数进行比较,我找不到任何特别之处。

尝试获取函数的sizeof,然后从非捕获 lambda 中获取。您会注意到该函数没有大小(因此无法编译),而 lambda 有(几乎总是 1)!

因此编译器无法为非捕获 lambda 生成普通函数。请注意,它可以在 as-if 规则下为 lambda 函数实现异常,但我不会将其称为普通函数。

通过使调用运算符静态或解决它(编译器可以做很多我们不能做的事情),到函数指针的转换可以工作。

【讨论】:

  • 谢谢,编译器在幕后做了很多事情。
  • sizeof 函数不合法
  • @bigxiao 是的,编译器基本上可以为所欲为,只要按照标准说的做。
  • @PasserBy 嗯,是的,这就是我的观点。我的回答就这么不清楚吗?如果您能提出更好的措辞方式,我将不胜感激
  • 我认为编译器(作为扩展)可能会允许它。至于sizeof([]{}),也不保证为1。这也可能因编译器而异。
【解决方案2】:

结构函子相对于常规函数的优势在于您可以保留类型,这可能有助于内联:

std::sort(std::begin(v), std::end(v), &function);

必须将 &function 的值记住为 bool (*)(const T&, const T&) 才能允许内联。

而,对于:

std::sort(std::begin(v), std::end(v),
          [](const T& lhs, const T& rhs){ return function(lhs, rhs);});

只要我们拥有comparer,我们就会拥有价值。无需额外工作即可记住初始值

【讨论】:

    猜你喜欢
    • 2021-09-04
    • 1970-01-01
    • 2021-02-10
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多