gpt4 book ai didi

c++ - 如何编写使用临时容器的范围管道?

转载 作者:行者123 更新时间:2023-12-02 10:28:50 29 4
gpt4 key购买 nike

我具有带有此签名的第三方功能:

std::vector<T> f(T t);

我也有一个名为 T的现有潜在无限范围( of the range-v3 sort)的 src。我想创建一个将 f映射到该范围的所有元素并将所有 vector 及其所有元素展平为单个范围的管道。

本能地,我会写以下内容。
 auto rng = src | view::transform(f) | view::join;

但是,这将不起作用,因为我们无法创建临时容器的 View 。

range-v3如何支持这样的范围管道?

最佳答案

range-v3禁止查看临时容器,以帮助我们避免创建悬空的迭代器。您的示例确切说明了为什么在 View 组合中必须使用此规则:

auto rng = src | view::transform(f) | view::join;

如果 view::join用来存储 begin返回的临时 vector 的 endf迭代器,则在使用之前,它们将失效。

“很好,Casey,但是为什么range-v3 View 不在内部存储这样的临时范围?”

因为表现。就像如何根据迭代器操作为O(1)来确定STL算法的性能一样, View 合成的性能也取决于 View 操作为O(1)的条件来确定。如果 View 将临时范围存储在“背后”的内部容器中,则 View 操作的复杂性(以及因此的组合)将变得不可预测。

“好吧,好的。鉴于我了解所有这些出色的设计,我该如何进行这项工作?!??”

由于 View 组合不会为您存储临时范围,因此您需要自己将它们转储到某种类型的存储中,例如:
#include <iostream>
#include <vector>
#include <range/v3/range_for.hpp>
#include <range/v3/utility/functional.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/join.hpp>
#include <range/v3/view/transform.hpp>

using T = int;

std::vector<T> f(T t) { return std::vector<T>(2, t); }

int main() {
std::vector<T> buffer;
auto store = [&buffer](std::vector<T> data) -> std::vector<T>& {
return buffer = std::move(data);
};

auto rng = ranges::view::ints
| ranges::view::transform(ranges::compose(store, f))
| ranges::view::join;

unsigned count = 0;
RANGES_FOR(auto&& i, rng) {
if (count) std::cout << ' ';
else std::cout << '\n';
count = (count + 1) % 8;
std::cout << i << ',';
}
}

请注意,此方法的正确性取决于 view::join是输入范围,因此是单次通过。

“这对新手不友好。哎呀,对专家也不友好。为什么在range-v3中没有对'临时存储实现™的某种支持?”

因为我们还没有解决问题,所以欢迎添加补丁;)

关于c++ - 如何编写使用临时容器的范围管道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63144622/

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