- 主题:lambda capture 的一个问题
今天有朋友跟我说这么干没问题:
void test() {
const string &s = some_func();
add_callback([s] {
do_something_to(s);
});
}
我的理解,这个 lambda 会被扩展成这样子:
class lambda {
const string &s;
operator () {}
};
一旦这个 lambda 离开了 test(),被 capture 的 s 就不对了。
而我朋友认为是这样:
class lambda {
const string s;
operatior () {}
};
有熟读标准的说说这个怎么回事吗?
--
FROM 110.81.42.*
写个例子跑一下?
--
FROM 45.77.25.*
#include <QtCore/qdebug.h>
#include <QtCore/qstring.h>
int main()
{
const QString &s = QString::fromUtf8("hello!");
qDebug() << &s;
([s] {
qDebug() << &s;
})();
return 0;
}
输出
0x7ffe678780a8
0x7ffe678780b0
说明我朋友说的是对的?
【 在 ble (ble) 的大作中提到: 】
: 写个例子跑一下?
--
FROM 110.81.42.*
[s]这个是capture by value吧,会复制一个, [&s]才是by reference
【 在 hgoldfish 的大作中提到: 】
: 今天有朋友跟我说这么干没问题:
: void test() {
: const string &s = some_func();
: ...................
--
FROM 115.193.175.*
规范有明确说明。这句:
“The type of such a data member is the referenced type if the entity is a reference to an object”。
ISO_IEC_14882__2020-12.pdf 这个在110页,"7.5.5.3 Captures"这一节的第10条:
10 An entity is captured by copy if
(10.1) — it is implicitly captured, the capture-default is =, and the captured entity is not *this, or
(10.2) — it is explicitly captured with a capture that is not of the form this, & identifier, or & identifier initializer.
For each entity captured by copy, an unnamed non-static data member is declared in the closure type. The
declaration order of these members is unspecified. The type of such a data member is the referenced type
if the entity is a reference to an object, an lvalue reference to the referenced function type if the entity
is a reference to a function, or the type of the corresponding captured entity otherwise. A member of an
anonymous union shall not be captured by copy.
--
FROM 221.218.165.*
Capture by value
[s]() {...}
Capture by reference
[&s]() {...}
这里是by value,所以会生成一个拷贝,所以没有问题。
【 在 hgoldfish 的大作中提到: 】
: 今天有朋友跟我说这么干没问题:
: void test() {
: const string &s = some_func();
: ...................
--
FROM 76.126.252.*
也就是说 [s] 一定会在 lambda 内部生成一个 const T 的字段是吗?其中 T 是原始类型?
外部是`T &&`, `const T&`, `volatile T`, `register T`, `union T`
这里一定会执行复制构造函数?
【 在 z16166 (Netguy) 的大作中提到: 】
: 规范有明确说明。这句:
: “The type of such a data member is the referenced type if the entity is a reference to an object”。
: ISO_IEC_14882__2020-12.pdf 这个在110页,"7.5.5.3 Captures"这一节的第10条:
: ...................
--
FROM 112.47.122.*
[s]生成的类型是s的类型去掉引用,大概相当于std::remove_reference吧
无论什么类型,肯定是拷贝
【 在 hgoldfish 的大作中提到: 】
: 也就是说 [s] 一定会在 lambda 内部生成一个 const T 的字段是吗?其中 T 是原始类型?
: 外部是`T &&`, `const T&`, `volatile T`, `register T`, `union T`
: 这里一定会执行复制构造函数?
: ...................
--
FROM 76.126.252.*
话说这句const string &s = some_func();
引用一个函数返回的对象安全吗?
【 在 hgoldfish (老鱼) 的大作中提到: 】
: 今天有朋友跟我说这么干没问题:
: void test() {
: const string &s = some_func();
: ...................
--
FROM 221.182.193.*
很多单型或者全局结构经常这样用的,比如一个全局的id到名字的查找表。
【 在 jimmycmh 的大作中提到: 】
: 话说这句const string &s = some_func();
: 引用一个函数返回的对象安全吗?
:
--
FROM 222.129.51.*