在嵌套 Lambda 中捕获 Lambda 的静态

2023-12-24

In 这个答案 https://stackoverflow.com/a/33282441/2642059我使用这段代码:

std::vector<std::vector<int>> imat(3, std::vector<int>(10));

std::for_each(imat.begin(), imat.end(), [&](auto& i) {
    static auto row = 0;
    auto column = 0;
    std::transform(i.begin(), i.end(), i.begin(), 
        [&](const auto& /*j*/) {
            return row * column++; 
    }); 

    ++row; 
});

但我注意到捕捉过程中有一些不当行为static auto row取决于编译器。

Clang 3.7.0 产量 http://coliru.stacked-crooked.com/a/fe3ef266452f39fe:

0 0 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7 8 9
0 2 4 6 8 10 12 14 16 18

gcc 5.1.0 产量 http://ideone.com/NTLmV2:

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Visual Studio 2015 给我一个编译时错误:

编译器中发生内部错误。

如果我将捕获嵌套捕获更改为捕获row我明确地收到编译器错误:

capture 中的标识符必须是在 lambda 的到达范围内声明的具有自动存储持续时间的变量

我可以捕捉一个static在嵌套的 lambda 中?看似合理,但问题却不少!

EDIT:

佛子指出 https://stackoverflow.com/questions/33285103/capturing-a-lambdas-static-in-a-nested-lambda?noredirect=1#comment54371126_33285103 that I can如果我将嵌套 lambda 的参数类型从const auto& to const int&。这看起来完全无关,但它确实有效。

如果我尝试捕获,这不起作用row明确地。在这种情况下,我仍然收到编译器错误:

capture 中的标识符必须是在 lambda 的到达范围内声明的具有自动存储持续时间的变量

我在这里报告了 Visual Studio 2015 错误:https://connect.microsoft.com/VisualStudio/feedback/details/1930409/capturing-a-lambdas-static-in-a-nested-lambda https://connect.microsoft.com/VisualStudio/feedback/details/1930409/capturing-a-lambdas-static-in-a-nested-lambda


内部编译器错误(ICE)始终是一个错误。

我们不需要捕获静态存储持续时间的变量,但我们确实需要捕获自动变量odr-used http://en.cppreference.com/w/cpp/language/definition#ODR-use。来自 C++ 标准草案部分5.1.2:

lambda 表达式的复合语句生成函数调用运算符的函数体 (8.4),但出于名称查找的目的(3.4),确定 this 的类型和值 (9.3.2) 并转换 idexpressions 使用 (*this) (9.3.1) 将非静态类成员引用到类成员访问表达式中,复合语句是在 lambda 表达式的上下文中考虑的。

so row应该在内部 lambda 中可见并且:

[...]如果 lambda 表达式 或通用 lambda odr 的函数调用运算符模板的实例化 - 使用 (3.2) this 或 a 从其到达范围起具有自动存储持续时间的变量,该实体应被捕获 lambda 表达式。[...]

仅需要捕获this以及自动存储持续时间的变量(如果它们是 ODR 使用的),我们可以看到显式捕获仅针对自动变量或this:

使用非限定名称查找的常用规则(3.4.1)来查找简单捕获中的标识符; 每次此类查找都应找到一个实体。由简单捕获指定的实体被认为是显式的 捕获,并且应该是这个或在到达范围内声明的具有自动存储持续时间的变量 本地 lambda 表达式。

为了使 Visual Studio 和 gcc 都与 clang 的结果相匹配,我可以移动row到全局命名空间,观看 gcc 直播 http://melpon.org/wandbox/permlink/eymPX8tI2KK2jQ09。正如 Fozi 指出的那样,改变const auto& /*j*/ to const int& /*j*/使它开始工作。

看起来 gcc 接受显式捕获非自动变量作为扩展,甚至然后显式捕获row例如[&, &row](const auto & )仍然产生全零。

如果我移动 gcc 的定义,则进一步row to main然后我看到以下错误(现场观看 http://melpon.org/wandbox/permlink/oZ8cRGniPT0RG06i):

/tmp/cchzwtQI.s: Assembler messages:
/tmp/cchzwtQI.s:1572: Error: symbol `_ZL3row' is already defined

对我来说这似乎是一个编译器错误。

我没有看到该标准的任何部分会使原始程序格式错误。也不应该改变auto to int做出改变并且不引入任何改变多态 lambda 提议 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3649.html似乎也可以解释这种差异。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在嵌套 Lambda 中捕获 Lambda 的静态 的相关文章

  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l

随机推荐

  • 最近的 Ubuntu 版本中有 libsresample 吗?

    我想知道哪个软件包涵盖了最新 Ubuntu 版本的 libswresample 也许还有早期版本 希望也包括 Debian 它完全被覆盖了吗 如果没有 我应该使用什么其他库来重新采样音频 最好是让它在任何地方都可以工作 即该库在任何地方都可
  • 将变量传递给 Flask WTForm

    我想使用从路由传入的默认值来执行查询选择字段 我不知道如何将变量从 View 传递到 Form 类 class transactionsForm Form loan id QuerySelectField trans id validato
  • unixaccept()函数两次返回相同的文件描述符

    我的多线程网络服务器程序有问题 我有一个正在侦听新客户端连接的主线程 我使用 Linux epoll 来获取 I O 事件通知 对于每个传入事件 我创建一个线程来接受新连接并为其分配一个 fd 在重负载下 可能会发生同一个 fd 被分配两次
  • Silverlight 的双击触发器

    Related Silverlight 中最简洁的单击 双击处理 https stackoverflow com q 1274378 1001985 在 XAML 中双击触发某些操作的最简单方法是什么 我正在尝试做这样的事情 当用户双击列表
  • 调用 WebService 并有 SSL/证书问题

    首先 我对 Java 中设置密钥库等知识了解不多 我正在尝试调用 SOAP Web 服务 我获取了 wsdl 生成了代码等 在我部署它并尝试触发 WS 调用之前 一切看起来都很好 这是我的设置 雄猫7 0 35 Java jdk 1 6 0
  • TFS 2015 CI - 具有 Web、控制台和 WCF 项目的解决方案中不会为控制台应用程序生成构建工件

    我正在使用 TFS 2015 CI 创建一个项目解决方案的持续集成 该解决方案结合了 Web 项目 WCF 项目 类库和控制台应用程序 该项目的结构如下所示 Project Solution Project 1 Web UI Project
  • 更改Gulp中文件的目标路径

    我尝试创建动态 gulp 任务 它将循环遍历所有文件和文件夹 并将其连接 编译到相应的文件夹中 文件夹结构例如 主题 框架 模块 module 1 assets css scss scss file 1 scss and 主题 框架 模块
  • 在etc文件夹中找不到php.ini?

    我对我的专用服务器有 root 访问权限 当我运行时phpinfo 它说我的 php ini 文件位于 etc 目录中 使用 ssh 我似乎无法在那里找到它 我不知道在哪里可以找到它 谢谢 这可能不是 SO 的问题 但这里有一些潜在的解决方
  • jQuery 的 hide 和 SlideUp 方法等效吗?

    Do slideUp slow and hide slow 会产生相同的动画效果吗 示例代码 document ready function hide click function p hide slow show click functi
  • 如何检测浏览器中的 HTML 5 兼容性

    检测浏览器对 HTML 5 语法兼容性的最佳方法是什么 并提示用户浏览器不兼容 我明白该教程展示了如何测试浏览器对 HTML5 的兼容性 http diveintohtml5 info everything html 但我很好奇这是不是唯一
  • Movie py:从内存中的文本到语音导入音频

    我正在尝试将 Azure 的文本转语音与movie py为视频创建音频流 result synthesizer speak ssml async xml string get stream AudioDataStream result 该过
  • 如何在C中使用GDI+?

    免责声明 我才刚刚开始学习 C 所以很可能我遗漏了一些明显的东西 或者没有以正确的方式思考 我究竟该如何在纯 C 中使用 GDI 据我了解 GDI 包装了为 C 制作的对象 但在它下面有一个平面 API 可以通过gdiplusflat h
  • 用于检测无效 UTF-8 字符串的正则表达式

    在PHP中 我们可以使用mb check encoding https www php net mb check encoding确定字符串是否为有效的 UTF 8 但这不是一个可移植的解决方案 因为它需要编译并启用 mbstring 扩展
  • 如何配置 yocto 使用最新的 git 提交?

    我是一个很懒的人 在处理硬件 软件项目时 软件会永久更改 在这个开发阶段 更改配方中的提交 恢复标签是非常令人讨厌的 我希望 Yocto 获取最新的 git 提交 这可能 如何做到这一点 我的示例食谱 SUMMARY my test SEC
  • Android Studio 是否可以构建一个以 .so 作为输出的本机模块

    我有几个 C 项目 目前使用 Android mk 文件和 ndk build 构建 由于这不太适合调试 所以我想将此 C 项目作为模块包含在我的 android studio 项目中 这个android studio项目目前是一个andr
  • 对于弱引用属性,为什么我应该更喜欢 unsafe_unretained 限定符而不是 allocate? [复制]

    这个问题在这里已经有答案了 可能的重复 使用 ARC 生命周期限定符 allocate 和 unsafe unretained https stackoverflow com questions 8397511 using arc life
  • 为什么Java能够将0xff000000存储为int?

    Java 中整数的最大值是 2147483647 因为 Java 整数是有符号的 对吗 0xff000000 的数值为 4278190080 但我看到的 Java 代码是这样的 int ALPHA MASK 0xff000000 有人可以启
  • PHP中如何删除点后的所有数字

    示例 1 123 gt 1 1 999 gt 1 thanks y 1 235251 x int y echo x will echo 1 Edit 使用显式转换为 int 是实现此目的的最有效方法 另外 转换为 int 会截断 后面的数字
  • 使用 cmd.exe 将长文件名转换为短文件名 (8.3)

    我正在尝试在 Windows 上将长文件名转换为短文件名 8 3 带有命令行参数的批处理文件按预期工作 短蝙蝠 echo OFF echo s1 calling short bat C Documents and Settings User
  • 在嵌套 Lambda 中捕获 Lambda 的静态

    In 这个答案 https stackoverflow com a 33282441 2642059我使用这段代码 std vector