考虑如何编写使用临时容器的范围管道?. 问题是如何T
使用给定的函数构建一个转换每个元素的视图
std::vector<T> f(T t);
在遵守限制 (借用那里的最佳答案)的同时
视图是一个轻量级的包装器,它以某种自定义方式呈现底层元素序列的视图,而无需对其进行变异或复制。视图的创建和复制成本很低,并且具有非拥有引用语义。
基本上,那里的所有答案似乎都同意,由于这种限制,它不能通过视图来完成。
我不明白这如何与支持partial_sum
.
考虑以下美化整数:
#include <vector>
#include <iostream>
#include <memory>
#include <range/v3/all.hpp>
using namespace ranges;
struct glorified_int {
explicit glorified_int(int i) : m_i{std::make_shared<int>(i)} {}
operator int() const { return *m_i; }
std::shared_ptr<int> m_i;
};
glorified_int operator+(const glorified_int &lhs, const glorified_int &rhs) {
glorified_int ret{(int)lhs + (int)rhs};
return ret;
}
它基本上只是将 an 包装int
在一个类中,将其存储在 an 中std::shared_ptr
,允许初始化、提取和添加。Wrt 非拥有引用语义,我看不出它与容器之间的根本区别,例如std::vector
.
但是,范围似乎没有问题适用partial_sum
于此:
int main() {
std::vector<glorified_int> vi{ glorified_int{1}, glorified_int{2} };
for(const auto &ps: vi | view::partial_sum())
std::cout << ps << std::endl;
打印出来
$ ./a.out
1
3
(美化的整数)3 在这里不是临时的吗?它当然不是原始序列的一部分。此外,显然,部分和是有状态的转换,那么范围如何保证
视图的创建和复制成本很低,并且具有非拥有引用语义。
视图与累积对象的复制成本一样高。
请注意,进一步链接它也没有问题(即,它不是一个动作):
vi | view::partial_sum() | view::take(10);
那有什么区别呢?
完整代码
#include <vector>
#include <iostream>
#include <memory>
#include <range/v3/all.hpp>
using namespace ranges;
struct glorified_int {
explicit glorified_int(int i) : m_i{std::make_shared<int>(i)} {}
operator int() const { return *m_i; }
std::shared_ptr<int> m_i;
};
glorified_int operator+(const glorified_int &lhs, const glorified_int &rhs) {
glorified_int ret{(int)lhs + (int)rhs};
return ret;
}
int main() {
std::vector<glorified_int> vi{ glorified_int{1}, glorified_int{2} };
for(const auto &ps: vi | view::partial_sum())
std::cout << ps << std::endl;
vi | view::partial_sum() | view::take(10);
}