c++ - "Lambdas are cheap"- 真的吗?在什么情况下?

标签 c++ lambda c++14

这篇文章声明使用 C++ Lambda 是“便宜的”:
Lambdas aren't magic - part 2
他们演示了如何将 lambdas 传递给现有的 std 函数/模板。
一篇文章演示了如何在不使用 std::function 的情况下使用“auto”作为函数的返回类型来返回 lambda。
我没有看到任何文章演示制作自己的功能,尤其是。类成员函数,它采用 lambda 或更多,而不使用 std::function。
所以这个“lambda 很便宜”的大胆声明——在现实世界的场景中真的是这样吗?
作为引用:对于我来说,“便宜”是为了解决这个问题:明智地用于具有数百 KB 内存和两位数 MHz 速度的嵌入式裸机项目。 (我一直在该领域使用 C++ 的一个健全的子集,并且正在寻找我还能使用的其他东西)
据我所见, std::function<> 并不便宜。一方面,作为 std::function 传递的 Lambda 显然无法再进行内联优化。
但更糟糕的是,一个 std::function<> 是 32 字节大。
同样显然,如果捕获的内容超出了范围,是否可以使用动态分配?
这一切听起来都是个坏消息。
因此,当我在寻找在没有 std::function 的情况下使用 lambdas 的方法时,只找到了一个返回 auto 的示例,我尝试了这个:
我制作了一个非常简单的类,它在成员函数中使用“auto”作为参数类型,编译器似乎对此很满意(尽管就预期的仿函数参数而言,它不像 std::function 那样“自我记录”代码)。

struct FuncyClass
{   unsigned func(auto fnx)
    {   return 2 * fnx(7);
    }
};

int main()
{   FuncyClass fc;
    auto result = fc.func( [](auto x){return x*3;} );
    
    printf("Result: %u\n", result);
    return 0;
}
// Output: "Result: 42"
但我有一种感觉,这个非常简单的场景并没有向我展示当它被更复杂的场景使用时可能会出现编译器错误泛滥。
我不太了解这种语法在幕后发生了什么,编译器在确定时会做什么,从仿函数的使用,期望什么参数和返回类型,以及这个带有自动参数的函数是如何在幕后实现的.
这真的是让你的类成员函数 lambda 可定制的明智方法吗?
然后它看起来“便宜”,因为在我的测试中,当使用 auto 而不是 std::function 时,可执行文件要小得多。
当然,它仍然是有限的:
如果不使用 std::function<> (或类似类型的 DIY 包装器),类就无法保留 lambda,对吗?
是否有可能防止动态分配发生,例如当出现需要 std::function 分配内存的场景时,是否会导致编译时错误?

最佳答案

Lambda 只是重载的对象 operator() .您可以在概念上将它们视为等同于:

class Lamba {
public:
    auto operator()(...) const { /* ... */ }
};
因此,它们并不比类似的函数调用更昂贵。 std::function没有必要使用 lambdas。您可以使用类型推导来存储/传递它们:
template <typename Func>
void foo(Func&& func) { /* ... */ }
对于非捕获 lambda,您可以使用 operator+ 将它们隐式或显式转换为函数指针:
void (*fp)(int) = [](int){ /* ... */ };
您的问题难以回答的原因是您在问 lambdas 是否昂贵。但是,与什么相比呢?如果您想知道它们在您的特定情况下是否具有足够的性能,您将不得不为自己做一些分析并弄清楚。

关于c++ - "Lambdas are cheap"- 真的吗?在什么情况下?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63597495/

相关文章:

c++ - 为其成员根据模板基类存在的类定义构造函数

java - 将 List<String> 中的分隔字符串转换为 List<String>

C++:如何创建两个互相使用的类

c++ - IF 语句中的多个 OR 或 AND 条件

c++ - 模板类成员使用类本身作为模板参数时出现未定义类错误

python - 了解给定 python 代码中的 lambda 用法

Java8 : Why a lambda expression could do a logical and(or) with boolean

c++ - 不完整类型无效应用 'Test::Impl'

c++ - std::get 以元组作为成员的自己的类

c++ - 如何使用命名空间系统;使用 VC++ 在 MFC 应用程序中