- 主题:lambda capture 的一个问题
Capture by value
[s]() {...}
Capture by reference
[&s]() {...}
这里是by value,所以会生成一个拷贝,所以没有问题。
【 在 hgoldfish 的大作中提到: 】
: 今天有朋友跟我说这么干没问题:
: void test() {
: const string &s = some_func();
: ...................
--
FROM 76.126.252.*
[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()是保证的RVO,效率一样,读代码的人不需要考虑是否安全这个问题。
代码应该写成一眼就知道是否正确,高手知道效率好不好。
不要写成一眼就知道效率好不好,但是高手才知道是否正确。
【 在 jimmycmh 的大作中提到: 】
: 话说这句const string &s = some_func();
: 引用一个函数返回的对象安全吗?
:
--
FROM 76.126.252.*
这样规定的目的有两个:
1. 引用即别名(alias)的规则。C++里几乎任何时候一个T&变量和它所指向的原始T变量用起来都是完全等价的。引用只是换个名字,不应该造成效果上的区别。
2. 功能合理性。以上面的例子为例:
const string& s = ...;
auto f = [s]() {...};
按现在的规则是s会被拷贝一份,那么这个lambda就是安全的。
如果把规则改成此时s被capture的是一个引用,那么怎么改代码才能让这个安全呢?我们得:
const string& s = ...;
const string s2 = s;
auto f = [s2]() {...};
可以看到为了保证安全我们被迫拷贝了两次。这是很糟糕的设计。
【 在 z16166 的大作中提到: 】
: 字面理解:
: s如果是引用(即&T、&&T。无论CV属性),[s]就会导致在闭包的内部定义一个T类型(而不是&T、&&T类型)的auto变量。
: 目的也是为了防止可能存在的dangling reference吧。
: ...................
--
FROM 76.126.252.*
lambda是11
capture by move是14
【 在 ziqin 的大作中提到: 】
: 我觉得标准这么定很顺理成章吧,毕竟c++是value semantic的,lambda在设计的时候,除了()里需要动态传入的变量,肯定也考虑了模拟全部变量的需求,那[]里的变量就是类似传入的全局变量,既然是传变量,肯定默认是value-semantic的,也就是copy一份。为了完善这个功能,capture by move也是11以后增加的。
:
--
FROM 76.126.252.*