将迭代器解引用到临时范围时出现非指针操作数错误

san*_*orn 4 c++ lazy-evaluation c++11 range-v3

运用

auto empty_line = [](auto& str){ return str.size() == 0; };
Run Code Online (Sandbox Code Playgroud)

我们做得到:

auto line_range_with_first_non_empty = 
                ranges::view::drop_while(ranges::getlines(std::cin),empty_line);
auto input1 = std::stoi(*line_range_with_first_non_empty.begin());
Run Code Online (Sandbox Code Playgroud)

我们也可以这样做:

auto line_range2 = ranges::getlines(std::cin);
auto iter2 = ranges::find_if_not(line_range2,empty_line);
auto input2 = std::stoi(*iter2);
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我尝试将以上版本缩短为:

auto iter3 = ranges::find_if_not(ranges::getlines(std::cin),empty_line);
// auto input3 = std::stoi(*iter3);
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

<source>:22:29: error: indirection requires pointer operand ('ranges::v3::dangling<ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::getlines_range::cursor> >' invalid)
    auto input3 = std::stoi(*iter3);
                            ^~~~~~
Run Code Online (Sandbox Code Playgroud)

我认为这是因为无限范围,但我错了.

auto sin = std::istringstream{"\n\n\nmy line\n"};
auto iter4 = ranges::find_if_not(ranges::getlines(sin),empty_line);
// Error when deref.
// auto input4 = std::stoi(*iter4);
Run Code Online (Sandbox Code Playgroud)

这会产生相同的错误.

<source>:27:29: error: indirection requires pointer operand ('ranges::v3::dangling<ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::getlines_range::cursor> >' invalid)
    auto input4 = std::stoi(*iter4);
                        ^~~~~~
Run Code Online (Sandbox Code Playgroud)

ranges::find_if一个范围作为右值时,为什么我不能取消引用?

是否ranges::getlines返回范围是多少?如果是这样,范围是否应该拥有东西?

godbolt.org/g/Yo6tKa

Eri*_*ler 8

如果传递给算法的范围是临时的,并且算法返回迭代器,则迭代器将包装在dangling包装器中,以防止您执行任何不安全的操作.任务完成.:-)