首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展用于boost::filtered的范围的生存期

扩展用于boost::filtered的范围的生存期
EN

Stack Overflow用户
提问于 2016-07-27 09:50:23
回答 1查看 419关注 0票数 0

我有一些类表现得像一个懒惰的容器,动态地生成值。然后,在某些情况下,我想过滤这些值。增强::范围::适配器::过滤似乎很适合。但是它不保留对“范围”的任何引用,它只存储开始/结束迭代器。

下面的代码模仿我的用例。但是它不起作用:container在使用r之前就被销毁了。

代码语言:javascript
复制
#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 << "Loop\n";
  for (auto i: r)
    std::cout << i << '\n';
}

其结果是(活码):

代码语言:javascript
复制
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的解决方案:对我来说依赖范围-v3可能还为时过早。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-27 17:58:58

所以这太恶心了。

诀窍是,您必须先存储容器,然后将管道应用到存储的容器中,然后假装是这样的。

代码语言:javascript
复制
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) )
  {}
};

现在,这需要用一个演绎的创建功能来完成,等等。

接下来,我们需要一种语法上很好的方法将该功能插入到现有的语法中。

一种方法是:

代码语言:javascript
复制
keep_a_copy( source ) | boost::adapters::filter( ... blah ... )

我们做一些柔道,让它神奇地工作,甚至在链子之后。

代码语言:javascript
复制
source | keep_source_copy( boost::adapters::filter( ... blah ... ) )

我觉得这比较容易。

我试了一试,虽然有点痛苦,但我并不认为任何根本不可能的事情。这肯定涉及到编写过多的代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38609517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档