使用 g++ 来自 [-Wdangling-reference] 可能出现误报

问题描述 投票:0回答:1

考虑以下代码:

#include <iostream>
#include <vector>
#include <ranges>

int main()
{
  std::vector<int> a{ 1, 2, 3, 4, 5 };
  
  std::span<const int> b{ a };

  for ( auto i : b | std::views::drop(1) )
    std::cout << i << '\n';
}

使用

-Wextra
编译它,g++ 13.2(或 13.1)会发出此警告:

<source>: In function 'int main()':
<source>:11:40: warning: possibly dangling reference to a temporary [-Wdangling-reference]
   11 |   for ( auto i : b | std::views::drop(1) )
      |                                        ^
<source>:11:40: note: the temporary was destroyed at the end of the full expression 'std::ranges::views::__adaptor::operator|<_Partial<std::ranges::views::_Drop, int>, std::span<const int>&>(b, ((const std::ranges::views::__adaptor::_RangeAdaptor<std::ranges::views::_Drop>*)(& std::ranges::views::drop))->std::ranges::views::__adaptor::_RangeAdaptor<std::ranges::views::_Drop>::operator()<int>(1))'

其他编译器和以前版本的 g++ 不会抱怨(参见例如 https://godbolt.org/z/Pf9YoWv57)。

这是误报还是我遗漏了什么?

c++ g++ std-ranges
1个回答
0
投票

range-for 循环大致等价于以下内容:

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

在您的情况下,

<range-expression>
b | std::views::drop(1)
,它返回一个临时对象,然后循环将引用该对象。
range-for
循环将延长由
<range-expression>
创建的任何临时对象的生命周期,直到循环结束,但是,根据您使用的 C++ 版本和编译器,循环可能会或可能不会延长任何中间对象的生命周期在
<range-expression>
.

内创建的临时文件

这可能是编译器警告您的内容。

© www.soinside.com 2019 - 2024. All rights reserved.