C++ 通过init capture的默认lambda捕获模式是什么样的?

C++ 通过init capture的默认lambda捕获模式是什么样的?,c++,c++11,lambda,c++14,effective-c++,C++,C++11,Lambda,C++14,Effective C++,对于lambdas,在C++11中,我们可以将默认捕获模式设置为按值/按引用,例如,[=]/[&],对于某些变量,可以选择后跟显式捕获,按引用/按值,例如,[=,&此_为按引用的_]或[&,此_为按值的_] 在C++14中,我们还可以通过move进行显式捕获,例如[y=std::movex] 使用init捕获无法表达的一点是默认捕获模式[…] 作者最可能指的是什么 我们已经有了一种方法,可以通过复制或引用来捕获我们需要的所有变量。为什么我们要用x=y的形式来表达呢 也许作者只是指默认情况下的移

对于lambdas,在C++11中,我们可以将默认捕获模式设置为按值/按引用,例如,[=]/[&],对于某些变量,可以选择后跟显式捕获,按引用/按值,例如,[=,&此_为按引用的_]或[&,此_为按值的_]

在C++14中,我们还可以通过move进行显式捕获,例如[y=std::movex]

<有效的现代C++,第32条,第三段,我读< /P> 使用init捕获无法表达的一点是默认捕获模式[…]

作者最可能指的是什么

我们已经有了一种方法,可以通过复制或引用来捕获我们需要的所有变量。为什么我们要用x=y的形式来表达呢


也许作者只是指默认情况下的移动捕获?在正文中使用的所有变量都会像[x=std::movex,y=std::movey,…]一样工作?

该段指出,无法将初始捕获与默认捕获模式[&]或[=]相结合,并且移动语义没有新的默认捕获模式

我们已经有了一种方法,可以通过复制或复制来捕获所需的所有变量 参考为什么我们要用x=y的形式来表达呢

你的想法是正确的。将init捕获与默认捕获相结合将具有与旧的默认捕获方式相同的行为。也许这就是它被省略的原因。然而,initcapture可以做一些以前做不到的新事情。就像给一个新变量赋值一样

也许作者只是指默认情况下的移动捕获? 类似于[x=std::movex,y=std::movey, …]是否列出了正文中使用的所有变量

这也是事实

为了更好地理解init capture的新可能性,我给您举一个小例子。假设要用0到n的值填充向量。使用lambda执行此操作的旧方法是:

std::vector<int> vec;
int i = 0;
std::generate_n(std::back_inserter(vec), n, [i]()mutable{
    return i++;
});
现在使用init capture,您可以在lambda capture中初始化计数变量:

std::vector<int> vec;
std::generate_n(std::back_inserter(vec), n, [i=0]()mutable{
    return i++;
});

这在以前是不可能的,在很多地方都很有用。

该段指出,不可能将init capture与默认捕获模式[&]或[=]相结合,并且移动语义没有新的默认捕获模式

我们已经有了一种方法,可以通过复制或复制来捕获所需的所有变量 参考为什么我们要用x=y的形式来表达呢

你的想法是正确的。将init捕获与默认捕获相结合将具有与旧的默认捕获方式相同的行为。也许这就是它被省略的原因。然而,initcapture可以做一些以前做不到的新事情。就像给一个新变量赋值一样

也许作者只是指默认情况下的移动捕获? 类似于[x=std::movex,y=std::movey, …]是否列出了正文中使用的所有变量

这也是事实

为了更好地理解init capture的新可能性,我给您举一个小例子。假设要用0到n的值填充向量。使用lambda执行此操作的旧方法是:

std::vector<int> vec;
int i = 0;
std::generate_n(std::back_inserter(vec), n, [i]()mutable{
    return i++;
});
现在使用init capture,您可以在lambda capture中初始化计数变量:

std::vector<int> vec;
std::generate_n(std::back_inserter(vec), n, [i=0]()mutable{
    return i++;
});

这在以前是不可能的,在很多地方都很有用。

由@OutOfBound给出的答案已经很好了。我只会从不同的角度表达类似的观点

Scott Meyers在第32项的前几段中指出:

在C++11中引入的捕获语法被认为是不令人满意的,即使在采用该标准时也是如此。 其原因是缺乏使用移动语义或(例如)常量引用进行捕获的方法,除非可能有一些笨拙、模糊的解决方法。 标准委员会本可以通过简单地扩展C++11语法来改进它的功能,例如引入[&&&,&&&x],但最终选择了一种不同的、更通用的方法:他们引入了一种新的语法C++14语法。 然后Scott注意到,原则上,您几乎可以完全忘记旧的C++11语法,而只使用C++14语法,即带有捕获初始化的语法。 只有使用旧语法才能真正做到的事情是定义默认捕获模式。 然而,史葛阻止C++程序员使用默认捕获模式无论如何项31。 因此,句子的含义是:在实践中,C++程序员或C++语言不需要旧的语法,我希望新的语法已经在C++ 11中被采纳。
还请注意,新的捕获语法非常灵活,它不仅可以表达您使用移动语义的意图,还可以用于常量引用,Scott省略了后一点和可变lambdas。

由@OutOfBound给出的答案已经很好了。我只从不同的角度表达类似的观点。

Scott Meyers在第32项的前几段中指出:

在C++11中引入的捕获语法被认为是不令人满意的,即使在采用该标准时也是如此。 其原因是缺乏使用移动语义或(例如)常量引用进行捕获的方法,除非可能有一些笨拙、模糊的解决方法。 标准委员会本可以通过简单地扩展C++11语法来改进它的功能,例如引入[&&&,&&&x],但最终选择了一种不同的、更通用的方法:他们引入了一种新的语法C++14语法。 然后Scott注意到,原则上,您几乎可以完全忘记旧的C++11语法,而只使用C++14语法,即带有捕获初始化的语法。 只有使用旧语法才能真正做到的事情是定义默认捕获模式。 然而,史葛阻止C++程序员使用默认捕获模式无论如何项31。 因此,句子的含义是:在实践中,C++程序员或C++语言不需要旧的语法,我希望新的语法已经在C++ 11中被采纳。 还请注意,新的捕获语法非常灵活,它不仅可以表达您使用移动语义的意图,还可以用于常量引用,Scott省略了后一点和可变lambdas。

init capture是[z=y]类型的捕获

使用这种捕获方式无法表达的唯一捕获类型是默认捕获模式。即:

[&, z=y]{ /* some code */ }
这里&使用的是旧式的捕获语法。它表示我们有一个默认的捕获模式。z=y是新型的init捕获

无法使用init capture来表示默认捕获模式

使用旧式捕获语法执行的任何其他操作,都可以使用init捕获语法进行复制

即:

是另一种表达方式

[x]{ /* some code */ }
[&x]{ /* some code */ }

是另一种表达方式

[x]{ /* some code */ }
[&x]{ /* some code */ }
现在这还没那么深

但是如果你的论点是不要使用旧的捕获语法,你应该证明你不再需要它了。除了定义默认捕获模式外,您不需要使用旧的捕获语法。

init capture是[z=y]样式的捕获

使用这种捕获方式无法表达的唯一捕获类型是默认捕获模式。即:

[&, z=y]{ /* some code */ }
这里&使用的是旧式的捕获语法。它表示我们有一个默认的捕获模式。z=y是新型的init捕获

无法使用init capture来表示默认捕获模式

使用旧式捕获语法执行的任何其他操作,都可以使用init捕获语法进行复制

即:

是另一种表达方式

[x]{ /* some code */ }
[&x]{ /* some code */ }

是另一种表达方式

[x]{ /* some code */ }
[&x]{ /* some code */ }
现在这还没那么深


但是如果你的论点是不要使用旧的捕获语法,你应该证明你不再需要它了。除定义默认捕获模式外,您不需要使用旧的捕获语法。

如果没有更多的上下文,这似乎很难回答,而且不是所有人都有这本书。@aschepper回答困难并不意味着这是一个无效的问题;如果没有更多的上下文,这似乎很难回答,而且不是我们所有人都有这本书。@aschepper回答困难并不意味着这是一个无效的问题;什么是const&like的捕获+1,顺便说一句。[&cr=std::as_constx],参见;另外:std::as_const随C++17提供,因此Scott Meyers肯定没有提及它。无论如何,很高兴知道这个用法。是的,它附带了c++17的标准库,但可能已经在c++11中实现了。我认为大多数人可以在lambdas中不使用const引用,因为lambdas通常很短,并且在受限的环境中使用,因此他们的手动管理不会有什么坏处。。。我经常写一个相当长的lambda。我写了一个lambda而不是一个函数,因为我不能传递后者。我写了一个lambda,而不是一个带有操作符的手工构造的结构,因为读者很清楚,前者是用来调用的,而他们必须浏览后者,让操作符理解它是可调用的。不过,对不起,这是OT。什么是const&like的捕获+1,顺便说一句。[&cr=std::as_constx],参见;另外:std::as_const随C++17提供,因此Scott Meyers肯定没有提及它。无论如何,很高兴知道这个用法。是的,它附带了c++17的标准库,但可能已经在c++11中实现了。我认为大多数人可以在lambdas中不使用const引用,因为lambdas通常很短,并且在受限的环境中使用,因此他们的手动管理不会有什么坏处。。。我经常写一个相当长的lambda。我写了一个lambda而不是一个函数,因为我不能传递后者。我编写了一个lambda,而不是一个带有操作符的手工构造的结构,因为读者很清楚,前者是用来调用的 ed,而他们必须浏览后者,以便操作员理解它是可调用的。不过,对不起,这是一个错误。