推论lambda捕获类型
Deducing Lambda Capture Types
我最近发现,通过lambda中的值捕获const
对象,这意味着LabMDA的身体内部的变量(即Lambda的数据成员(也是const
。例如:
const int x = 0;
auto foo = [x]{
// x is const int
};
在c 17的草案中,第8.1.5.2节中提到了这种行为:
对于通过复制捕获的每个实体,闭合类型中都声明了一个未命名的非静态数据成员。这 这些成员的声明顺序未指定。这种数据成员的类型是引用类型 如果实体是对对象的引用 是对功能的引用,或相应捕获的实体的类型,否则。一个成员 匿名工会不得被副本捕获。
我希望推论类型的捕获变量与推论自动相同。
是否有充分的理由为被捕获的类型制定不同的类型降低规则?
在您的示例中,由于lambda不是mutable
,因此无法修改x
,这使函数调用call oterator const
。但是,即使lambda是 mutable
,它的确是引用的段落在lambda const int
中的 x
类型。
如果我没记错的话,这是C 11中的故意设计决定,以在Lambda内使用x
的行为与封闭范围中使用x
相似。也就是说,
void foo(int&);
void foo(const int&);
const int x = 0;
foo(x); // calls foo(const int&)
auto foo = [x]() mutable {
foo(x); // also calls foo(const int&)
};
,这有助于避免错误,例如,例如,, 有些代码从具有明确循环到使用lambda的标准库算法。
调用标准库算法。如果我对此回忆说错了,希望有正确答案的人会介入并写下自己的答案。
不是推理的答案;这里已经有一个全面的答案。
对于那些想知道如何捕获const变量的非const副本的人,您可以使用pinitialiser使用捕获:
const int x = 0;
auto foo = [x = x]() mutable {
// x is non-const
};
虽然需要C 14。C 11兼容的解决方案是使lambda之外的副本:
const int x = 0;
int copy = x;
auto foo = [copy]() mutable {
// copy is non-const
};
原因是lambda中的 operator()
默认为 const
。
int main()
{
const int x = 0;
auto foo = [x](){}; // main::$_0::operator()() const
foo();
}
因此您必须使用mutable
lambda:
int main()
{
const int x = 0;
auto foo = [x=x](){}; // main::$_0::operator()()
foo();
}
有充分的理由对捕获类型有不同的类型否定规则?
这是故意的决定(以下CWG 756引用了理由/理由(,并且是重写原始Lambda提案的一部分,
- N2550:lambda表达式和封闭:单态lambdas的措辞(修订4(
- N2927:C 0x lambdas的新措辞(修订2(
在2009年3月在萨米特举行的会议上,与C 0x有关的许多问题Lambdas由核心工作组(CWG(提出和审查。在决定清晰之后对于大多数此类问题,CWG得出的指示,最好重写本节在Lambdas上实施该方向。本文提出了此重写。
特别是其CWG 756的分辨率[重点 mine]:
- CWG 756.闭合对象成员删除CV-CALIFIFICAL
[...]考虑以下示例:
void f() { int const N = 10; [=]() mutable { N = 30; } // Okay: this->N has type int, not int const. N = 20; // Error. }
也就是说,是闭合对象的成员的n不是const,即使捕获的变量是const。这似乎很奇怪, as捕获基本上是捕获本地环境的一种手段避免终身问题的方式。更认真地,类型的更改表示声明,超载分辨率和模板的结果参数扣除应用于lambda内的捕获变量表达可能与包含包含的范围的表达方式不同lambda表达式,它可能是错误的微妙来源。
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 在 lambda 捕获中声明的变量的类型推导
- C++ 模板类型的静态 lambda 成员的构造
- Clang 工具,用于提取给定 lambda 类型的 lambda 主体
- 如果 lambda 没有指定的类型,std::function 如何接受 lambda?
- Lambda可以用作非类型模板参数吗
- 如何确定捕获不可复制参数的 lambda 的类型?
- 如何制作可以接受任何类型的参数的 std::函数和 lambda
- C++模板函数中,指定回调函子/lambda 的参数类型,同时仍允许内联?
- 运算符中的不同类型? 具有无捕获,相同的签名,lambda
- 通过参数传递 lambda(无函数类型模板)
- 有没有办法根据 lambda 参数返回类型部分专用化我的模板化函数?
- 如何推导lambda的返回类型
- 尽管显式声明了返回类型,但对lambda的调用是不明确的
- 是否创建具有不同返回类型的lambda
- 防止 lambda 的返回类型扣除
- 在 lambda 函数 g++-4.8 中调用继承的受保护子类型
- 在 lambda 中从引用类型捕获的值的类型,不使用通用捕获
- 我可以让返回类型自动处理具有相同签名但捕获不同内容的 lambda 吗?
- 复制分配C++相同类型的 lambda