C++11/14/17 Lambda 引用捕获 [&] 不复制 [*this]

2024-02-23

参考这个线程:https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0806r2.html https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0806r2.html

It says:

换句话说,一个默认捕获 ([&]) 以拼写出冗余的方式捕获 *this,但另一个捕获 ([=]) 以非冗余方式捕获它。

这表示在 c++17 之前, [=] 捕获this作为值,并且 [&] 将捕获 [*this],这是不明确的。所以我进行了一个快速测试,看看 [&] 是否默认捕获 [*this]。

我的测试代码尝试查看 [&] 是否默认捕获 *this,然后应该调用复制构造函数,并且对其值的任何更改都不会影响原始对象,因为它是副本。

#include<iostream>
using namespace std;
class M{
    int mI;
public:
    M() : mI(3) { cout << "ctor\n"; }
    ~M() { cout << "dtor\n"; }
    M(const M& m) {
        if (this != &m) {
            cout << "copy ctor\n";
            mI = m.mI;
        }
    }
    M& operator=(const M& m) {
        if (this != &m) {
            cout << "operator =\n";
            mI = m.mI;
        }
        return *this;
    }

    void CaptureByValue() {
        auto f1 = [=] () { // capture this
            cout << mI << '\n';
            ++(this->mI);
        };
        f1();
        cout << mI << '\n';
    }
    void CaptureByReference() {
        auto f1 = [&] () { // capture *this
            cout << mI << '\n';
            ++(this->mI);
        };
        f1();
        cout << mI << '\n';
    }
};

int main() {
    {
        M obj1;
        obj1.CaptureByValue();
    }
    cout << "------------\n";
    {
        M obj2;
        obj2.CaptureByReference();
    }
    return 0;
}

编译并运行它:

clang++ LambdaCapture.cpp -std=c++11 && ./a.out
clang++ LambdaCapture.cpp -std=c++14 && ./a.out
clang++ LambdaCapture.cpp -std=c++17 && ./a.out

所有案例打印:

ctor
3
4
dtor
------------
ctor
3
4
dtor

我的问题:

(1)结果出乎我的意料:没有调用任何copyctorCaptureByReference并且更改的值会影响原始值this目的。测试代码没有促进 cpp17 中的 lambda 语法更改。

(2) 我什至无法将捕获更改为 [=, *this] 或 [&, *this],因为编译器会说:

LambdaCapture.cpp:25:13: error: read-only variable is not assignable
            ++(this->mI);
            ^ ~~~~~~~~~~

很奇怪,怎么出来的read-only这里的变量,至于this指针。


感谢您的解释。


  • [=], [this], [=, this] and [&, this]所有捕获this按价值。也就是说,它复制了指针的值this.
  • [&]捕获*this引用。那是,thislambda 中是一个指向*this在 lambda 之外。

上述版本的效果this因此 lambda 中的值将是相同的。

  • [=, *this]复制捕获的所有元素并复制*this- 不是this指针。
  • [&, *this]引用所有捕获的元素,但复制*this.
LambdaCapture.cpp:25:13: error: read-only variable is not assignable
            ++(this->mI);
            ^ ~~~~~~~~~~

那是因为 lambda 是const默认情况下。你需要让它们mutable以便能够改变它们。

auto f1 = [&, *this]() mutable { // made mutable
    cout << mI << '\n';
    ++(this->mI);                // now ok
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11/14/17 Lambda 引用捕获 [&] 不复制 [*this] 的相关文章

  • LINQ TO ENTITY 无法与枚举类型进行比较

    下面是枚举叶子 public enum Leaves Annual 0 Medical 1 Hospitalization 2 Unpaid 3 下面是linq查询 public ActionResult ApproveLeave int
  • 在opencv中保存帧而不压缩

    我正在尝试使用写 OpenCV 函数 我想保存帧 TIFF扩大 我遇到的问题是保存的图像被压缩 所以我无法使用它们 知道如何摆脱这种压缩吗 提前致谢 不要介意西奇说的话 TIFF 标志通过 LZW 压缩硬编码在 opencv 二进制文件中
  • 在运行时配置 ASP.NET 会话状态

    我们有一个使用 SQL Server 会话状态的 ASP NET 网站 状态配置在Web config like
  • 如何让我的方法等待所有线程完成?

    我有一个方法可以触发线程来完成一些工作 将有 2 个线程异步运行一段时间 当调用它们的回调方法时 回调会触发另一个线程 直到所有工作完成 如何让我的方法等待所有这些线程完成并被触发 如果这是 Net 4 0 您可以使用CountdownEv
  • 如何更改 GridView 内 ListViewItemPresenter 中的 SelectedBackground

    我在 SubSection 中有一个 Clickable Gridview
  • 为什么 C++11/Boost `unordered_map` 在擦除时不重新散列?

    我想知道为什么 C 11 和 Boost 的 hashmap 在通过迭代擦除元素时不会调整大小 即使这在技术上不是内存泄漏 我认为这可能是应用程序中的一个严重问题 这对我来说是一个隐藏的问题 很难追踪它 并且它实际上可能会影响许多应用程序
  • EWS 消息跟踪报告

    我一直在研究如何使用 EWS 从交换中获取消息跟踪报告 但似乎无法查明任何内容 我打算构建一个抓取日志文件的应用程序 但如果我可以通过 EWS 来完成它 那对我正在做的事情会更好 有任何想法吗 我终于能够为我的问题创建一个解决方案 我在 C
  • C# 中的异步方法如何工作?

    我在我的一些项目中使用异步方法 我喜欢它 因为它使我的应用程序更具可扩展性 但是 我想知道异步方法如何在后台真正工作 NET 或 Windows 如何知道调用已完成 根据我进行的异步调用的数量 我可以看到创建了新线程 但并不总是 为什么 此
  • Clang 使用 -nostdlib 生成崩溃代码

    我正在尝试为可执行文件设置自己的运行时环境 但无法使用 clang v3 4 1ubuntu1 目标 x86 64 pc linux gnu 来生成没有段错误的可执行文件 我已将问题简化为以下内容 如果我有一个文件 crt1 c 除了满足
  • 如何对具有无效值的属性使用 JSON.net 的默认值

    我正在使用 Newtonsoft JSON 库来反序列化来自 Web 服务的响应 问题是某些字段包含无效值 例如 一条记录上的一个字段包含一个 T 表示该字段应该是数字 我想做的是将无效字段的值设置为 null 或其他默认值 我的所有属性都
  • cuda中有模板化的数学函数吗? [复制]

    这个问题在这里已经有答案了 我一直在寻找 cuda 中的模板化数学函数 但似乎找不到 在普通的 C 中 如果我调用std sqrt它是模板化的 并且将根据参数是浮点数还是双精度数执行不同的版本 我想要这样的 CUDA 设备代码 我的内核将真
  • 更改子进程中的 iostream

    现在 我正在开发一个项目 其中我需要启动一个子进程来使用 C 在 Linux 中执行一个新程序 并且我需要重定向标准输入和输出 就像在 C 中一样 它们是cin and cout 到一个文件 这意味着在子进程中 标准输入和输出都是文件 子进
  • LINQ 中的左外连接

    下面的代码不断给我一个错误消息 你调用的对象是空的 var partsWithDefaults from partsList1 in p join partsList2 in d on new PartNo partsList1 PartN
  • 如何避免函数的多重定义(Linux、GCC/G++、Code::Blocks)

    我有一个代码块项目 它使用许多不同的文件 通常是由其他程序员编写的 目前我遇到的情况是 我有两个不同的子项目 其中包含以相同方式命名的函数 比方说 F int x 因此 F int x 是在两个不同位置的两个源文件中定义的 并且它们有两个不
  • 初学者友好的方法来获取所有文件和目录的列表

    使用 NET 3 0 我得到了下面的方法 它可以正确返回指定目录的所有文件和目录 以及子目录 的集合 如果可能的话 我想将其简化为仅使用我非常熟悉的结构 具体来说 有以下几点我不太清楚 1 IEnumerable
  • 如何将 typedef 结构传递给函数?

    此刻我正在努力 void avg everything 但这给了我错误 error subscripted value is neither array nor pointer 当我今天早些时候收到此错误时 这是 因为我没有正确地将 2D
  • GridView,在代码中添加标题行第 2 部分

    这是这篇文章的延续 但添加了完整的代码 ASP NET GridView 在代码中添加标题行 https stackoverflow com questions 19119004 asp net gridview adding header
  • Web 服务无法使用 GAC 中的类型创建类型错误

    遇到一个不寻常的问题时 我似乎喜欢做一些不常见的事情 我有一个复合控件 它检查给定的 Web 服务文件是否存在于我的应用程序的根目录中 如果不存在 它会在标记中创建带有必要指令的文件以进行滚动 如下所示 反过来 它被保存到输出中 完成此步骤
  • 如何让c代码执行hex机器代码?

    我想要一个简单的 C 方法能够在 Linux 64 位机器上运行十六进制字节码 这是我的 C 程序 char code x48 x31 xc0 include
  • 在.Net中使用ObjectCache缓存对象并设置过期时间

    我陷入了一个场景 我的代码如下 更新 它不是关于如何使用数据缓存 我已经在使用它及其工作 它是关于扩展它 以便该方法在到期时间和从外部源获取新数据之间不会进行调用 object string this GetDataFromCache ca

随机推荐

  • iPhone - UIImagePickerControllerDelegate 继承

    我添加了一个UIImagePickerController to a UIViewController 我还分配了UIImagePickerControllerDelegate对此UIViewController 当我执行以下行时 myPi
  • Discord.js 计时器,定期更新倒计时

    我目前正在制作一个计时器命令 用户可以输入类似 prefix timer 10m 的内容 机器人将启动一个 10 分钟的计时器 并且每 20 30 秒它会自我更新一次 但我不确定我该怎么做它 提前致谢 一种可能的方法是使用setInterv
  • Doctrine DQL 从关系表中删除

    使用 Doctrine 2 和 Symfony 2 0 我有两个 Doctrine 实体 假设 EntityA 和 EntityB 他们之间有多对多关系 这样数据库中就创建了一个EntityA EntityB表 使用 DQL 或 Query
  • Clojure core.match 无法在类上匹配

    当评估这个超级简单的 core match 表达式时 我得到 match class 3 14 Integer Integer Double Doubler gt Integer 这怎么可能是正确的 我是否遗漏了有关 core match
  • 如何通过python执行shell脚本

    我有一个脚本 abc sh 其中包含带有标志的命令列表 例子 abc sh echo FLAG name cp FLAG file1 FLAG file2 echo file copied 我想通过python代码执行这个脚本 说 xyz
  • RSpec - 测试强参数 ActionController::ParameterMissing

    如何测试某一行为是否会引发ActionController ParameterMissing例外 例如 it raises an exception do post create expect response to raise Actio
  • 如何在 Ruby 中读取文件的行

    我试图使用以下代码从文件中读取行 但是当读一个file http dl dropbox com u 559353 rss20 xml txt 内容全部在一行 line num 0 File open xxx txt each do line
  • Swift 将 AnyObject 转换为 Block

    因此 我使用 Salesforce SDK 并为整个 SDK 构建了桥接标头 它们提供了一个块语法 但尚未转换成最有用的代码 例如 func sendRESTRequest request SFRestRequest failBlock S
  • 在模板内对 $data 进行双向绑定

    我正在尝试设置通用的 Knockout 模板 可以根据数据类型在编辑和只读模式之间切换 如果您曾经使用过 ASP NET 的动态数据 它就像它们的字段模板 例如 这是这样使用的
  • 可以单独编译任何 .c 文件(即没有 main ?)

    我目前有一个 类似库 的 c 文件 如下所示 我有两个问题 如果我想看看它本身是否编译得很好 我该怎么做 如果我尝试 gcc 它 它总是会给出 no main 错误 这是有道理的 但会引发一个问题 知道给定的 c 文件是否可以在 隔离 中编
  • 迭代错误数组时出现 Swift 内存泄漏

    我对 Swift 比较陌生 所以我希望我没有问一个愚蠢的问题 我有一些实例化类型数组的代码Error 稍后将被迭代并打印到控制台 当使用 Leaks 工具通过 Instruments 运行此代码时 它显示了泄漏 SwiftNativeNSE
  • 如何使用jquery、express和handlebars创建无刷新页面?

    我正在学习 Express JS 我的问题是 我想使用 NodeJS 创建两个页面 它使用把手作为模板引擎 但我希望第一页应该使用发送res render home 第二个页面应该由 jQuery 使用 ajax 调用来调用 以表达并从表达
  • “错误:<路径> 属性 d:预期数字,“MNaN、NaNLNaN、NaNL…”。“ D3 错误

    我正在从 Quandl 的 API 导入一些数据 以制作多年来布伦特油价的图表 我正在提供来自 Angular 发出的 HTTP 请求的数据 不知何故 所提供的数据没有被读取为数字 因为我收到以下错误 错误 属性 d 预期数字 MNaN N
  • 设计 Vuetify 选择器的样式

    选择器的 Vuetify 组件是
  • TMonthCalendar 和 Delphi 样式 (Delphi XE2)

    TMontCalendar 似乎是一个 Windows 包装器 因此它不会受到新的 VCL 样式的影响 您知道解决方案吗 The TMonthCalendar http docwiki embarcadero com Libraries e
  • 当 Angular 完成向 DOM 添加范围更新时,如何触发方法?

    我正在寻找一种在向 scope 变量 在本例中为 scope results 添加更改后执行代码的方法 我需要这样做是为了调用一些遗留代码 这些代码要求项目位于 DOM 中才能执行 我的真实代码是触发 AJAX 调用 并更新作用域变量以更新
  • 如何使用 Sunspot 设置具有多对多关系的构面搜索?

    我之前没有实现过搜索功能 感觉有点卡住 我有一个太阳黑子搜索功能 可以根据关键字查找结果 这非常有效 但我现在想实现多选方面功能 但我什至不知道如何设置基本的方面搜索 我有多对多的关系 在 Rails 中而不是在现实生活中 类人 has m
  • 静态方法中的 Lock()

    我有一个多线程应用程序 它使用静态方法写入设置 xml 文件 我想避免文件同时更新两次 导致访问 写入异常 我怎么做 这不起作用 namespace Program public class Settings private static
  • DatePicker 未显示泰国文化的正确年份(2021 年应为 2564)

    我正在开发一个支持各种语言 文化的应用程序 但是 DatePicker 控件对于泰国文化来说似乎有问题 我尝试使用 ThreadCulture 也尝试过 CultureInfo CurrentCulture 或 CultureInfo Cu
  • C++11/14/17 Lambda 引用捕获 [&] 不复制 [*this]

    参考这个线程 https www open std org jtc1 sc22 wg21 docs papers 2018 p0806r2 html https www open std org jtc1 sc22 wg21 docs pa