Vio*_*ffe 9 c++ lambda language-lawyer c++11
以下代码
void CMainWindow::someMethod(const CLocationsCollection& parentItem)
{
auto f = [this, parentItem.displayName](){};
}
Run Code Online (Sandbox Code Playgroud)
给我一个错误:
错误C2143:语法错误:'.'之前缺少']'
如果我想parentItem.displayName通过ref 捕获,我会为它创建一个非依赖别名标识符:
const QString& name = parentItem.displayName;
auto f = [this, &name](){}; // Or should it be [this, name] ?
Run Code Online (Sandbox Code Playgroud)
但是我需要通过价值来捕捉它,我不想捕捉整体,parentItem因为它很重.有解决方案吗
PS捕获列表中的名称必须是标识符.parentItem.displayName(作为一个整体)不是一个标识符?为什么编译器无法正确解析?
Fil*_*efp 14
注意:本文中的所有标准参考均来自C++标准草案n3337.
该标准规定一个捕获必须是&,=,this,的标识符,或一个标识符由preceeded &.
5.1.2Lambda表达式[expr.prim.lambda]Run Code Online (Sandbox Code Playgroud)capture-list: capture ..._opt capture-list , capture ..._opt capture: identifier & identifier this
既然parentItem.displayName不是标识符,而是"类成员访问表达式".拒绝你的代码片段时编译器是正确的.
5.2.5p1类成员访问权限[expr.ref]后缀表达式后跟一个点
.或箭头->,可选地后跟关键字template(14.2),然后是id-expression,后缀表达式.评估点或箭头之前的后缀表达式; 66该评估的结果与id-expression一起确定整个后缀表达式的结果.
在C++ 14中,您将能够使用init-capture来规避手头的问题,看作下面的代码片段.它将使用名称display_name创建一个捕获,使用parentItem.displayName的值初始化.
[display_name = parentItem.displayName](){ ... };
Run Code Online (Sandbox Code Playgroud)
遗憾的是,C++ 11中没有这样的功能.因此,问题的解决方案是对数据成员进行本地引用,然后在创建lambda时捕获该引用.
auto& lmb_display_name = parentItem.displayName;
[lmb_display_name](){ ... }; // the lambda will have a copy of `parentItem.displayName`
Run Code Online (Sandbox Code Playgroud)
注意:您的原始帖子似乎暗示lambda的捕获列表中的引用 R的名称将使lambda包含对R引用的引用的引用,这是不正确的,正如此片段所示.
| 归档时间: |
|
| 查看次数: |
1943 次 |
| 最近记录: |