Kra*_*ntz 3 c++ copy-elision c++17
lambda 表达式(作为返回值)中的按值捕获 ( [x]) (或 C++14 移动捕获[x = std::move(x)])中的复制(移动)构造是否可能(或保证)被省略?
auto param_by_value(Widget w) {
// manipulating w ...
return [w] { w.doSomeThing(); };
}
auto param_by_move(Widget w) {
// manipulating w ...
return [w = std::move(w)] { w.doSomeThing() };
}
auto local_by_value() {
Widget w;
// manipulating w ...
return [w] { w.doSomeThing(); };
}
auto local_by_move() {
Widget w;
// manipulating w ...
return [w = std::move(w)] { w.doSomeThing() };
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
w可能(甚至保证)被省略?(我记得显式std::move有时会阻止复制省略,并且参数的复制/移动是不可能被省略的。)w调用 的移动构造函数Widget?std::move,应优先选择哪一个作为最佳实践?Lambda 捕获本质上是 Lambda 对象的成员变量。因此,无论是在初始化还是在 lambdaoperator()重载中使用,它们都不会受到任何形式的省略。
并且由于构造函数/析构函数调用是可观察的行为,因此不允许编译器在“好像”规则下不调用它们(除非编译器可以看到这些构造函数/析构函数的代码并且可以证明不存在可见的副作用)它们的影响。除其他外,它还必须在整个代码库中遵循该 lambda 的路径。所以基本上,不要指望它)。
话虽这么说,根据 C++17 规则返回 lambda 本身不会调用 lambda 本身的复制/移动,因此不需要对该 lambda 的成员进行进一步的复制/移动。
w 的按值捕获会调用 Widget 的移动构造函数吗?
不会。按值捕获总是复制。
| 归档时间: |
|
| 查看次数: |
393 次 |
| 最近记录: |