1

例子:

SomeType bar::foo() const {
  SomeType retVal;
  for (auto i = 0u; i < 10; ++i) {
    retVal = boost::range::join(retVal, m_someDataContainer.equal_range(i));
  }
  return retVal;
}


可以说,为简单起见, m_someDataContainer 和 bar 类定义如下:

typedef boost::multi_index_container<
    int, bmi::indexed_by<bmi::hashed_unique<bmi::tag<struct someTag>,
                                           bmi::identity<int>>>> Data;
class bar {
public:
  SomeType foo() const;

private:
  Data m_someDataContainer;
};

问题是:如何确定 foo() 的返回类型以及如何在不使用 boost::any_range 的情况下加入这些范围

EDIT1:看起来这是不可能的,在以前的连接值上调用join in loop会使结果类型成为joined_range的joined_range的嵌套类型...

4

1 回答 1

1

由于您拥有(或可以生成)一系列相同类型的范围,因此您需要一个展平范围在一系列范围内使用迭代中的flatten杰西古德:

return flatten(boost::irange(0, 10)
    | boost::adaptors::transform(
        [this](int i){ return m_someDataContainer.equal_range(i); }));

不幸的是,我认为这可能会使迭代器悬空,因此您应该调整flatten那里以将范围复制到其返回值中;你可以通过多重继承来做到这一点:

template<typename Cont> using FlatIteratorRange
    = boost::iterator_range<flattening_iterator<decltype(std::declval<Cont>().begin())>;

template<typename Cont>
struct FlatRange
    : private Cont
    , public FlatIteratorRange<Cont>
{
    explicit FlatRange(Cont const& c)
        : Cont(c)
        , FlatIteratorRange<Cont>(
            flat_iter(this->Cont::begin(), this->Cont::end()),
            flat_iter(this->Cont::end()));
    {}
}

template<typename Cont>
auto flatten(Cont const& c) -> FlatRange<Cont>
{
    return FlatRange<Cont>(c);
}
于 2015-02-04T17:41:41.123 回答