延长boost::filtered范围的生存期
Extend lifetime of a range for boost::filtered
我有一些类的行为就像一个惰性容器,动态生成值。然后在某些情况下,我想过滤这些值。Boost::range::adapter::filtered似乎非常适合。但是,它不保留对"范围"的任何引用,只存储开始/结束迭代器。
下面的代码模仿了我的用例。但它不起作用:container
在使用r
之前就被销毁了。
#include <iostream>
#include <vector>
#include <boost/range/adaptor/filtered.hpp>
#define PING() std::cerr << __PRETTY_FUNCTION__ << 'n'
using ints = std::vector<int>;
struct container
{
container() { PING(); }
~container() { PING(); }
using value_type = typename ints::value_type;
using iterator = typename ints::iterator;
using const_iterator = typename ints::const_iterator;
iterator begin() { PING(); return std::begin(c_); }
iterator end() { PING(); return std::end(c_); }
const_iterator begin() const { PING(); return std::cbegin(c_); }
const_iterator end() const { PING(); return std::cend(c_); }
ints c_ = { 1, 2, 3, 4, 5 };
};
int main()
{
auto r = container{} | boost::adaptors::filtered([](auto&& v) { return v % 2; });
std::cerr << "Loopn";
for (auto i: r)
std::cout << i << 'n';
}
它导致(实时代码):
container::container()
const_iterator container::begin() const
const_iterator container::end() const
const_iterator container::end() const
const_iterator container::end() const
container::~container()
Loop
1
3
5
有没有一种简单的方法可以确保每个人都能在我需要的时候活多久?当然,在main
中,我可以声明一个变量来存储container{}
,但这不适合我在现实世界中使用,因为这个容器实际上是通过查询一些对象获得的;我不希望客户不得不处理这个问题。
似乎最简单的方法是重写filtered
的某个版本,以保留该范围的副本,但我想寻找一种避免编写过多代码的解决方案。我真的在寻找Range-v2的解决方案:对我来说,依赖Range-v3可能还为时过早。
所以这很糟糕。
诀窍是,您必须首先存储容器,然后将管道应用于存储的容器,然后假装为类似的范围。
template<class X>struct store{ X data; };
template<class Src, class Range>
struct save_src_range:
private store<Src>,
Range
{
// boilerplate for copy/move goes here (TODO)
template<class S, class RangeFactory>
save_src_range( S&& s, RangeFactory&& f ):
store<Src>{std::forward<S>(s)},
Range( std::forward<RangeFactory>(f)(this->data) )
{}
};
现在,这需要用一个推导的创建函数等来装饰。
接下来,我们需要一种语法上很好的方法来将该功能插入到现有语法中。
一种方法是:
keep_a_copy( source ) | boost::adapters::filter( ... blah ... )
在那里我们做一些柔道,让它神奇地发挥作用,甚至可能在链结之后。
或
source | keep_source_copy( boost::adapters::filter( ... blah ... ) )
我觉得这比较容易。
我刺了它一刀,它有点疼,但我没有看到任何根本不可能的事情。这肯定涉及到编写太多的代码。
相关文章:
- GCC对可能有效的代码抛出init list生存期警告
- 在不复制临时对象的情况下延长其生存期
- 结束另一个线程中使用的对象的生存期
- "this"指针的值在对象的生存期内是否恒定?
- 创建具有全局生存期的 UObject
- C++17 和静态临时生存期的参考扩展
- 数组对象的生存期是否在重用其元素存储时结束?
- 从“if constexpr”分支扩展对象生存期/范围
- 为什么免费存储区中对象的生存期绑定到范围
- 对范围和堆内存生存期感到困惑
- 范围内临时对象的生存期是多少?
- C++ 中静态局部变量的范围和生存期
- 封闭环变量的生存期和范围是什么
- 基于范围的 for 循环的对象生存期问题
- 表达式范围内的临时生存期
- 静态变量生存期、文件范围与函数范围
- C++向量、常量字符*、变量范围和生存期
- 变量的范围与生存期
- 延长boost::filtered范围的生存期
- c++ 循环中变量的范围和生存期"for"