g++ 不允许在 lambda 中通过引用对 const 对象进行广义捕获?

     2023-04-18     124

关键词:

【中文标题】g++ 不允许在 lambda 中通过引用对 const 对象进行广义捕获?【英文标题】:g++ won't allow generalized capture of const object by reference in lambda? 【发布时间】:2015-11-02 08:23:54 【问题描述】:

这被 g++(4.9.3 和 5.2.0)拒绝,但被 clang 3.5.0 接受:

int main()  
    const int ci = 0;
    auto lambda = [ &cap = ci ]()  ;

g++ 给出error: binding ‘const int’ to reference of type ‘int&’ discards qualifiers。似乎 g++ 拒绝允许捕获非常量引用,当然除了使用普通的旧 C++11 捕获 [&ci]。这似乎是一个非常奇怪的约束,也许是 g++ 中的一个错误?

【问题讨论】:

***.com/questions/3772867/… @CoryKramer,这个问题确实密切相关。我今天也评论了这个问题。我想我的问题是:“给定一个 const 对象,我如何通过引用来捕获它?”。而这个问题是“给定一个 non-const 对象,我如何通过 const 引用捕获它?”。我想一个好的答案会涵盖这两个问题。 【参考方案1】:

您的代码有效。 §5.1.2/11 去

init-capture 的行为就好像它声明并显式捕获了形式为 “auto init-capture ; 的变量”,其声明区域是 lambda-expressioncompound-statement […]

现在,明确地声明

auto &cap = ci;

捕获cap 很好。也就是说,

int main()  
    const int ci = 0;
    auto &cap = ci;
    auto lambda = [&cap]()  ;

compiles with GCC。除了cap的声明区域和生命周期之外,这个sn-p和你的没有区别,因此GCC是不正确的。 这个错误已经被报告为#66735,还有一个类似的例子:

int x = 0;
auto l = [&rx = static_cast<const int&>(x)] ;

【讨论】:

这样的话,我会尽快报告的。我非常惊讶以前没有注意到这个错误 - 它似乎是一个如此简单的例子。我肯定不是第一个尝试通过引用捕获 const 对象的人吗? @AaronMcDaid 你不是,但使用初始化捕获通过引用捕获const 对象可能很少发生。 This report 非常相似。我可能会用我稍微简单的例子来评论那个错误。 @AaronMcDaid 谢谢。我会将其纳入答案中。 我在尝试通过 const 捕获非 const 对象时发现了这一点,首先将其 const 转换为 const。但是,是的,捕获一个已经是 const 的对象(即我的问题)会很奇怪!【参考方案2】:

这看起来类似于gcc bug: [C++14] lambda init-capture fails for const references,它说:

这段代码编译失败:

int main() 
    int x = 0;
    auto l = [&rx = static_cast<const int&>(x)]() ;

错误信息是:

test.cpp:3:14: 错误:将“const int”绑定到“int&”类型的引用 丢弃限定符

auto l = [&rx = static_cast<const int&>(x)]() 

但是根据 [expr.prim.lambda]/11 rx 应该被捕获为 auto &rx = static_cast(x),即为 const int&。

错误报告引用 [expr.prim.lambda]/11 说:

init-capture 的行为就好像它声明并显式捕获了“auto init-capture ;”形式的变量 其声明区域是 lambda 表达式的复合语句,除了 [...]

【讨论】:

为啥在 PHP 中通过引用传递?

】为啥在PHP中通过引用传递?【英文标题】:WhyPassingbyReferenceinPHP?为什么在PHP中通过引用传递?【发布时间】:2016-03-3104:18:07【问题描述】:我写了一个函数,它应该接受一些变量,然后改变这些变量的值。但是,运行该函数后... 查看详情

在函数中通过引用向 data.table 添加新列并不总是有效

】在函数中通过引用向data.table添加新列并不总是有效【英文标题】:Addingnewcolumnstoadata.tableby-referencewithinafunctionnotalwaysworking【发布时间】:2015-01-2123:13:11【问题描述】:在编写依赖于data.table的包时,我发现了一些奇怪的行为。... 查看详情

在Java中通过引用传递字符串?

】在Java中通过引用传递字符串?【英文标题】:PassingaStringbyReferenceinJava?【发布时间】:2010-11-1905:41:24【问题描述】:我习惯在C做以下事情:voidmain()StringzText="";fillString(zText);printf(zText);voidfillString(StringzText)zText+="foo";输出是:foo... 查看详情

在 C# 中通过引用或值传递对象

】在C#中通过引用或值传递对象【英文标题】:PassingObjectsByReferenceorValueinC#【发布时间】:2018-04-0311:52:45【问题描述】:在C#中,我一直认为非原始变量通过引用传递,原始值通过值传递。因此,当将任何非原始对象传递给方法... 查看详情

osgi框架中通过bundlecontext对象对服务的注册与引用

BundleActivator在每个Bundle新建时都会默认生成Activator类,该类实现了BundleActivator类,实现了其start()和stop()两个方法 BundleContext框架运行时,容器中存有唯一的BundleContext对象,与Spring容器中唯一的ApplicationContext对象同理,再后期随... 查看详情

如何在没有 lambda 函数的 React Native 中通过单个处理程序处理几个 TextInput?

】如何在没有lambda函数的ReactNative中通过单个处理程序处理几个TextInput?【英文标题】:HowtohandleafewTextInputbysinglehandlerinReactNativewithoutlambdafunction?【发布时间】:2020-04-1000:46:41【问题描述】:我需要在ReactNative应用程序中通过单个... 查看详情

在C中通过引用传递数组?

】在C中通过引用传递数组?【英文标题】:PassinganarraybyreferenceinC?【发布时间】:2010-11-0913:38:09【问题描述】:如何在C中通过引用传递结构数组?举个例子:structCoordinateintX;intY;;SomeMethod(Coordinate*Coordinates[])//DoSomethingwiththearrayintm... 查看详情

在 C++ 11 线程中通过引用传递;更改已本地化

】在C++11线程中通过引用传递;更改已本地化【英文标题】:passingbyreferenceinC++11threads;changesarelocalized【发布时间】:2015-02-1506:20:43【问题描述】:我正在尝试使用C++11线程加快对opencv代码的一些处理。与此同时,我正在使用矢量... 查看详情

在 C 和 C++ 中通过指针访问结构

】在C和C++中通过指针访问结构【英文标题】:AccessingstructviapointerinCandC++【发布时间】:2019-07-0308:58:47【问题描述】:简短的“简单”问题:为什么会这样JNIEnv*g_env=NULL;(*g_env)->ExceptionDescribe(g_env);在gcc(C)中编译但不是在g++(C++)中... 查看详情

在 C++ 中通过引用和值传递字符串

】在C++中通过引用和值传递字符串【英文标题】:PassingstringsbyreferenceandvalueinC++【发布时间】:2015-04-0801:53:28【问题描述】:我想声明一个字符串,通过引用传递它来初始化它,然后通过值传递给\'outputfile\'函数。下面的代码有... 查看详情

在 C++ 中通过引用传递对象

】在C++中通过引用传递对象【英文标题】:passingobjectbyreferenceinC++【发布时间】:2013-08-1109:45:02【问题描述】:在C++(也是C)中通过引用传递变量的常用方法如下:void_someFunction(dataType*name)//dataTypee.gint,char,floatetc./****definition*/intm... 查看详情

在 C 中通过引用传递字符串

】在C中通过引用传递字符串【英文标题】:passstringsbyreferenceinC【发布时间】:2010-12-2404:49:47【问题描述】:我无法弄清楚如何通过函数的参数将字符串传回。我是编程新手,所以我想这可能是一个初学者问题。您可以提供的任... 查看详情

在java中通过引用等效?

我有两个类来查看和控制模型中的两个对象。视图/控件类是JPanels。其中一个对象包含一个设备,另一个保存该设备的配置。我正在初始化负责视图/控制配置的类,然后我正在初始化设备的视图/控件,在构造函数中传递配置。... 查看详情

有人可以解释在 C++ 中通过指针传递和通过引用传递的目的是啥吗?

】有人可以解释在C++中通过指针传递和通过引用传递的目的是啥吗?【英文标题】:Cansomeoneexplainwhatpurposepassingbypointerandpassingbyreferencehaveinc++?有人可以解释在C++中通过指针传递和通过引用传递的目的是什么吗?【发布时间】:201... 查看详情

在 AWS Lambda 函数中通过 AWS SES 发送电子邮件

】在AWSLambda函数中通过AWSSES发送电子邮件【英文标题】:SendingemailviaAWSSESwithinAWSLambdafunction【发布时间】:2015-12-1300:49:33【问题描述】:我在AWSLambda上创建了一个非常基本的简单函数,用于接受表单提交。该功能的一部分是将电... 查看详情

无法在 MySQLi 中通过引用传递参数 [重复]

】无法在MySQLi中通过引用传递参数[重复]【英文标题】:CannotpassparameterbyreferenceinMySQLi[duplicate]【发布时间】:2011-07-3100:08:23【问题描述】:我试图将一个字符串传递给我的MySQLi准备语句,但它给了我错误:不能在MySQLi中通过引用... 查看详情

在 Boost::Python 中通过引用传递

】在Boost::Python中通过引用传递【英文标题】:PassbyreferenceinBoost::Python【发布时间】:2010-03-1702:37:39【问题描述】:考虑类似:structParameterinta;Parameter()a=0;voidsetA(intnewA)a=newA;;structMyClassvoidchangeParameter(Parameter&p)p.setA(-1);;好吧, 查看详情

在 PHP 中通过引用返回

】在PHP中通过引用返回【英文标题】:ReturnbyreferenceinPHP【发布时间】:2011-11-1907:35:06【问题描述】:我尝试了谷歌搜索,尝试了PHP文档,搜索了StackOverflow的答案,但找不到任何令人满意的东西。我正在读一本书,其中作者使用... 查看详情