在 C 11 Lambda 中通过引用捕获引用
此代码片段演示了在 lambda 表达式中通过引用捕获整数引用:
<code class="cpp">#include <functional> #include <iostream> std::function<void()> make_function(int& x) { return [&]{ std::cout << x << std::endl; }; } int main() { int i = 3; auto f = make_function(i); i = 5; f(); }</code>
此代码是否保证在不调用未定义行为的情况下输出 5?
该代码确实保证在不调用未定义行为的情况下工作。与按值捕获 ([= x]) 相反,按引用捕获 ([&x]) 利用 C 标准中的一个独特异常,允许引用在其生命周期之外持续存在。这是因为 lambda 表达式捕获的引用被实现为 lambda 闭包类型的成员访问。
范围和生命周期注意事项
需要注意的是,到达范围规则因为 lambda 纯粹是语法上的,在这种情况下不起作用。引用的实体 x 在 lambda 的可达范围内,可以捕获。
标准写法
根据 [expr.prim.lambda]/17根据 C 标准,只有通过 copy 捕获的表达式才会转换为 lambda 闭包类型的成员访问。通过引用捕获的表达式只是保持不变,并继续表示原始实体。
此外,该标准没有明确解决引用在其生命周期之外使用的问题。但是,由于在其生命周期之外使用引用不会受到任何惩罚(除非从其自己的初始化程序或前面的类成员引用),因此允许此代码按预期运行。
结论
在 C 11 lambda 中通过引用捕获引用保证按预期工作,输出引用整数的更新值,而不会调用未定义的行为。这是基于 lambda 捕获的标准定义,以及在某些特定上下文中使用生命周期之外的引用时缺乏惩罚的规定。
以上是在 C 11 Lambda 中通过引用捕获引用是否保证输出更新的值?的详细内容。更多信息请关注PHP中文网其他相关文章!