假设我有一个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)模式吗?
取自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 之前不会完成任何工作。
既然您说临时范围可以被认为是一个容器,那么您的函数就会返回一个悬空引用。
换句话说,您需要确保基础范围比视图更持久,否则您就会遇到麻烦。
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |