首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >除非用std::ref包装,否则复制C++11 lambda捕获

除非用std::ref包装,否则复制C++11 lambda捕获
EN

Stack Overflow用户
提问于 2018-01-21 13:43:38
回答 1查看 125关注 0票数 0

当将参数传递给std::bind时,它们总是被复制或移动,除非被std::ref和我想用lambda表达式包装。问题是,我希望将lambda表达式的生成封装在一个函数中,并将用户传递给lambda的参数转发给lambda。我想这样做的原因是,我想异步调用lambda,让用户决定参数是通过引用还是通过复制传递。

考虑下面的例子。我有一个函数print_address,它以参数作为引用。然后我有一个函数combine_and_call_bind,它将参数转发到std::bind

代码语言:javascript
复制
void print_address(int& a) {
  std::cout << "Adress of a = " << &a << std::endl;
}

template<typename F, typename Args>
void combine_and_call_bind(F f, Args&& args) {
  auto a = std::bind(f, std::forward<Args>(args));

  a();
}

如果要将参数复制到combine_and_call_bind-function中,或者通过将参数包装在std::ref中以引用方式传递参数,则用户可以在调用std::ref时指定

代码语言:javascript
复制
combine_and_call_bind(print_address, a); // copy a into std::bind
combine_and_call_bind(print_address, std::ref(a)); // pass a as reference into std::bind

在使用combine_and_call_lambda时,如何对下面的函数C++11做同样的操作?

代码语言:javascript
复制
template<typename F, typename Args>
void combine_and_call_lambda(F f, Args&& args) {
  auto a = [/* std::forward<Args>(args) */, f] {
    f(args);
  };

  a();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-21 14:18:10

您可以尝试按值捕获所有内容:

代码语言:javascript
复制
template<typename F, typename... Args>
void combine_and_call_lambda(F f, Args&&... args) {
    auto a = [=]() mutable {
        f(args...);
    };

    a();
}

然后使用:

代码语言:javascript
复制
combine_and_call_lambda(print_address, a);
combine_and_call_lambda(print_address, std::ref(a));

演示

正如我们在兰卜达所看到的

捕获--以逗号分隔的零或多个捕获列表,可选择以捕获默认值开头。 捕获列表可以按以下方式传递(详见下文): ..。 =通过复制捕获lambda主体中使用的所有自动变量,如果存在引用,则捕获当前对象。

因此,在上面的代码中,所有内容都被复制并存储在lambda对象中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48367438

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档