草庐IT

c++ - 在嵌套 Lambda 中捕获 Lambda 的静态

coder 2023-06-03 原文

this answer我使用此代码:

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 yields :

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 yields :

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 给我一个编译时错误:

An internal error has occurred in the compiler.

如果我将捕获嵌套捕获更改为显式捕获 row 我会收到编译器错误:

identifier in capture must be a variable with automatic storage duration declared in the reaching scope of the lambda

我可以在嵌套的 lambda 中捕获 static 吗?看起来是合法的,但是问题太多了!

编辑:

Fozi pointed out如果我将嵌套 lambda 的参数类型从 const auto& 更改为 const int& 。这似乎完全不相关,但确实有效。

如果我尝试显式捕获 row,这将不起作用。在那种情况下,我仍然会收到编译器错误:

identifier in capture must be a variable with automatic storage duration declared in the reaching scope of the lambda

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

最佳答案

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

我们不需要捕获静态存储持续时间的变量,但我们需要捕获自动变量odr-used .来自草案 C++ 标准部分 5.1.2:

The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator, but for purposes of name lookup (3.4), determining the type and value of this (9.3.2) and transforming idexpressions referring to non-static class members into class member access expressions using (*this) (9.3.1), the compound-statement is considered in the context of the lambda-expression.

所以 row 应该在内部 lambda 中可见,并且:

[...]If a lambda-expression or an instantiation of the function call operator template of a generic lambda odr-uses (3.2) this or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the lambda-expression.[...]

只有 this 和自动存储持续时间的变量在 odr-used 时才需要捕获,我们可以看到显式捕获仅针对自动变量或 this 定义:

The identifier in a simple-capture is looked up using the usual rules for unqualified name lookup (3.4.1); each such lookup shall find an entity. An entity that is designated by a simple-capture is said to be explicitly captured, and shall be this or a variable with automatic storage duration declared in the reaching scope of the local lambda expression.

为了让 Visual Studio 和 gcc 都匹配 clang 的结果,我可以将 row 移出到全局命名空间 see it live for gcc .正如 Fozi 指出的那样,将 const auto&/*j*/ 更改为 const int&/*j*/ 使其开始工作。

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

如果我将 row 的定义移动到 main 则进一步了解 gcc,然后我会看到以下错误 ( see it live ):

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

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

我没有看到标准的任何部分会使原始程序格式错误。将 auto 更改为 int 也不应该产生影响,并且不会影响 polymorphic lambda proposal 引入的更改。似乎也可以解释这种差异。

关于c++ - 在嵌套 Lambda 中捕获 Lambda 的静态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33285103/

有关c++ - 在嵌套 Lambda 中捕获 Lambda 的静态的更多相关文章

  1. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  2. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. Ruby——嵌套类和子类是一回事吗? - 2

    下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby​​解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc

  5. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  6. ruby-on-rails - 使用回形针的嵌套形式 - 2

    我有一个名为posts的模型,它有很多附件。附件模型使用回形针。我制作了一个用于创建附件的独立模型,效果很好,这是此处说明的View(https://github.com/thoughtbot/paperclip):@attachment,:html=>{:multipart=>true}do|form|%>posts中的嵌套表单如下所示:prohibitedthispostfrombeingsaved:@attachment,:html=>{:multipart=>true}do|at_form|%>附件记录已创建,但它是空的。文件未上传。同时,帖子已成功创建...有什么想法吗?

  7. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  8. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  9. ruby - 如何让Ruby捕获线程中的语法错误 - 2

    我正在尝试使用ruby​​编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?

  10. ruby-on-rails - 无法在 Rails 助手中捕获 block 的输出 - 2

    我在使用自定义RailsFormBuilder时遇到了问题,从昨天晚上开始我就发疯了。基本上我想对我的构建器方法之一有一个可选block,以便我可以在我的主要content_tag中显示其他内容。:defform_field(method,&block)content_tag(:div,class:'field')doconcatlabel(method,"Label#{method}")concattext_field(method)capture(&block)ifblock_given?endend当我在我的一个Slim模板中调用该方法时,如下所示:=f.form_field:e

随机推荐