我可以将临时管道返回到范围操作吗?

Bér*_*ger 9 c++ range-v3

假设我有一个generate_my_range对 a range(特别是 is regular)建模的类。那么下面的代码是否正确:

auto generate_my_range(int some_param) {    
  auto my_transform_op = [](const auto& x){ return do_sth(x); };
  return my_custom_rng_gen(some_param) | ranges::views::transform(my_transform_op);
}
auto cells = generate_my_range(10) | ranges::to<std::vector>;
Run Code Online (Sandbox Code Playgroud)

my_custom_rng_gen(some_param)采取按值(第一)管道运营商,还是我有一个参考晃来晃去,一旦我离开generate_my_range scope ?

函数调用会一样ranges::views::transform(my_custom_rng_gen(some_param),my_transform_op)吗?

如果我使用左值引用是否正确?例如:

auto generate_my_range(int some_param) {
  auto my_transform_op = [](const auto& x){ return do_sth(x); };
  auto tmp_ref = my_custom_rng_gen(some_param);
  return tmp_ref | ranges::views::transform(my_transform_op);
}
Run Code Online (Sandbox Code Playgroud)

如果这些操作的值采用范围,那么如果我将左值引用传递给容器,我该怎么办?我应该使用ranges::views::all(my_container)模式吗?

Rum*_*rak 1

取自Ranges-v3 文档

视图[...]具有非拥有引用语义。

拥有单个范围对象允许操作的管道。在管道中,范围以某种方式进行延迟适应或急切突变,结果立即可用于进一步适应或突变。延迟适应由视图处理,急切突变由操作处理。

// taken directly from the the ranges documentation
std::vector<int> const vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
using namespace ranges;
auto rng = vi | views::remove_if([](int i){ return i % 2 == 1; })
              | views::transform([](int i){ return std::to_string(i); });
// rng == {"2","4","6","8","10"};
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,rng 只是存储对基础数据以及过滤器和转换函数的引用。在迭代 rng 之前不会完成任何工作。

既然您说临时范围可以被认为是一个容器,那么您的函数就会返回一个悬空引用。

换句话说,您需要确保基础范围比视图更持久,否则您就会遇到麻烦。