gpt4 book ai didi

c++ - 将基于 C++11 范围的 for 循环与右值 range-init 一起使用是否安全?

转载 作者:IT老高 更新时间:2023-10-28 12:51:36 25 4
gpt4 key购买 nike

假设我有一个按值返回 std::vector 的函数:

std::vector<int> buildVector();

使用基于范围的 for 迭代结果似乎很自然:

for (int i : buildVector()) {
// ...
}

问题:这样做安全吗?

我对该标准的阅读(实际上是草案 n4431)表明它可能不是,尽管我很难相信委员会没有允许这种用法。我希望我的阅读不正确。

第 6.5.4 节定义了基于范围的 for:

for ( for-range-declaration : expression ) statement

使用以下脱糖:

{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}

其中 range-init 只是 ( expression ),至少对于类类型,begin-expr__range .begin()begin(__range)

在我的 buildVector 示例中,我认为 range-init 会产生一个临时文件,允许实现在 __range 之后立即销毁该临时文件引用是绑定(bind)的。这意味着 __range 引用可能在评估 begin-expr 时已经悬空。

当然,这样写应该总是安全的:

std::vector<int> notATemporary = buildVector();
for (int i : notATemporary) {
// ...
}

但我希望我不必将此添加到我的陷阱列表中。

最佳答案

是的,非常安全。

来自 [class.temporary]/4-5:

There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression. The first context is when a default constructor is called [...]

The second context is when a reference is bound to a temporary. The temporary to which the reference isbound or the temporary that is the complete object of a subobject to which the reference is bound persistsfor the lifetime of the reference except:

  • A temporary bound to a reference member in a constructor’s ctor-initializer [...]
  • A temporary bound to a reference parameter in a function call [...]
  • The lifetime of a temporary bound to the returned value in a function return statement [...]
  • A temporary bound to a reference in a new-initializer [...]

这些异常(exception)均不适用。因此,临时对象在引用的生命周期内持续存在,__range,即整个循环。

关于c++ - 将基于 C++11 范围的 for 循环与右值 range-init 一起使用是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30448182/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com