在类中存储 Lambda

发布于 2025-01-01 04:12:03 字数 841 浏览 0 评论 0原文

当需要将 lambda 存储为类成员以便可以推迟其调用时,最佳实践是什么?更具体地说,在下面的代码清单中存储传递给 deferred_lambda 类的 lambda 作为参考是否安全?如果不是,如果我将 lambda 作为值而不是引用存储在 deferred_lambda 中是否安全?

最后,与使用 g++ 进行常规函数调用相比,以这种方式将 lambda 存储为类成员是否会导致性能损失?也就是说,使用 deferred_lambda.invoke() 会比在实现相同操作的虚拟结构上调用operator() 慢吗?

使用 g++,我注意到 lambda 的大小随着我使用更多捕获的变量而增加。我认为这是可以预料的,因为根据我的理解,编译器在内部为 lambda 生成一个结构,其中包含必要的捕获变量作为成员。这一观察结果引发了我现在提出的问题,因为按值存储 lambda 在时间和内存方面可能比存储对它们的引用更昂贵。

template <class Func>
class deferred_lambda
{
    Func& func_;
public:
    deferred_lambda(Func func) : func_(func) {}
    void invoke() { func_(); }
};

template <class Func>
deferred_lambda<Func> defer_lambda(Func func)
{
    return deferred_lambda(func);
}

void foo()
{
    int a, b, c;
    auto x = defer_lambda([&]() { a = 1; b = 2; c = 3; });
} 

What is the best practice to use when one needs to store a lambda as a class member so that its invocation can be deferred? More specifically, is it safe to store the lambda passed to the class deferred_lambda in the code listing below as a reference? If not, would it be safe if I were to store the the lambda in deferred_lambda as a value instead of as a reference?

Finally, can I expect to incur a performance penalty in comparison to a regular function call with g++ for storing the lambda as a class member in this way? That is, would using deferred_lambda.invoke() be slower than a call to operator() on some dummy struct that would implement the same operations?

With g++, I noticed that the size of the lambda increases as I use more captured variables. I suppose that this is to be expected, since to my understanding, the compiler internally generates a struct for the lambda that contains the necessary captured variables as members. This observation is what led to the question that I am now asking, since storing lambdas by value may be more expensive in terms of time and memory than storing references to them would.

template <class Func>
class deferred_lambda
{
    Func& func_;
public:
    deferred_lambda(Func func) : func_(func) {}
    void invoke() { func_(); }
};

template <class Func>
deferred_lambda<Func> defer_lambda(Func func)
{
    return deferred_lambda(func);
}

void foo()
{
    int a, b, c;
    auto x = defer_lambda([&]() { a = 1; b = 2; c = 3; });
} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

挽袖吟 2025-01-08 04:12:03

我相信存储 lambda 以便以后执行的方法是使用 std::function 对象。根据库实现的不同,function 类应该具有必要的构造函数和转换器,以便将 lambda 或任何其他类型的函子或函数分配给它以供以后执行。

I believe the way to store a lambda for later execution is to use a std::function object. Depending on the library implementation the function class should have the necessary constructors and convertors to have a lambda, or any other sort of functor or function, assigned to it for later execution.

十雾 2025-01-08 04:12:03

更具体地说,在下面的代码清单中存储传递给 deferred_lambda 类的 lambda 作为参考是否安全?

不。在 defereed_lambda() 完成后,这将是一个悬空引用。

如果不是,如果我将 deferred_lambda 中的 lambda 作为值而不是引用存储是否安全?

是的。但您仍然必须确保在执行 lambda 时通过引用捕获的变量仍然有效。

也就是说,使用 deferred_lambda.invoke() 会比在实现相同操作的虚拟结构上调用 operator() 慢吗?

可能不会,没有理由。

这一观察结果引发了我现在提出的问题,因为按值存储 lambda 在时间和内存方面可能比存储对它们的引用更昂贵。

它仍然必须存储在某个地方......

More specifically, is it safe to store the lambda passed to the class deferred_lambda in the code listing below as a reference?

No. That would be a dangling reference after defereed_lambda() has finished.

If not, would it be safe if I were to store the the lambda in deferred_lambda as a value instead of as a reference?

Yes. But you still have to ensure variables captured by reference still live when executing the lambda.

That is, would using deferred_lambda.invoke() be slower than a call to operator() on some dummy struct that would implement the same operations?

Probably not, there's no reason for it.

This observation is what led to the question that I am now asking, since storing lambdas by value may be more expensive in terms of time and memory than storing references to them would.

It still has to be stored somewhere...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文