Igo*_*ack 14 c++ parameters lambda mutable
我似乎错过了C++中lambda机制的一些观点.这是代码:
std::vector<int> vec (5);
int init = 0;
std::generate(begin(vec), end(vec), [init]() mutable { return ++init; });
for (auto item : vec) {
std::cout << item << " ";
}
std::cout << std::endl << init << std::endl;
Run Code Online (Sandbox Code Playgroud)
如果没有mutable它就不会编译,因为我正在改变initlambda.
现在,我的理解拉姆达被每一个信息载体的一个项目新的全新副本的init是0,所以,1必须每次都返回.但这段代码的输出是:
1 2 3 4 5
0
它看起来像在执行开始时只generate复制init 一次.但为什么?它应该像这样工作吗?
Nat*_*ica 24
现在,正如我所知,lambda是为每个向量的项目调用的,其新的init副本为0.
这是不正确的.lambda只是另一种创建类并为其提供的operator()方法.[]lambda 的一部分描述了成员变量以及它们是通过引用还是值捕获的.该()拉姆达的组成部分,是参数列表operator()和{}部分是函数体.该mutable部分告诉编译器默认情况下使operator()非const原样const.
所以
[init]() mutable { return ++init; }
Run Code Online (Sandbox Code Playgroud)
变
struct compiler_generated_name
{
int init; // we captured by value
auto operator()() // since we used mutable this is non const
{
return ++init;
}
};
Run Code Online (Sandbox Code Playgroud)
我在这里使用了一个结构来简化输入,但是lambda被指定为类类型,因此class可以使用.
这意味着init相同init距离上一次迭代,你永远只能捕捉一次.记住这一点非常重要
auto generate_lambda()
{
int foo = 0;
return [&foo](){ return ++foo; };
}
Run Code Online (Sandbox Code Playgroud)
将为您提供一个悬挂引用,foo当函数返回时使用它是未定义的行为.
Vit*_*meo 10
lambda是一个编译器生成的结构,相当于:
struct lambda
{
int init = 0; // captured value
auto operator()() // non-const, due to `mutable`
{
return ++init;
}
};
Run Code Online (Sandbox Code Playgroud)
因此,init只在lambda中捕获并复制一次 - 多次调用lambda将不会init再次捕获.
您正在处理并看到 init 的初始值 - 您可能想要根据您的期望做的是init通过引用捕获......
std::vector<int> vec (5);
int init = 0;
std::generate(begin(vec), end(vec), [&init]() mutable { return ++init; });
for (auto item : vec) {
std::cout << item << " ";
}
std::cout << std::endl << init << std::endl;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10582 次 |
| 最近记录: |