使用非DefaultConstructible谓词来提升filter_iterator

时间:2015-11-05 23:53:17

标签: c++ boost

我想使用boost::filter_iterator的谓词看起来像这样:

  template<class tuple_t>
  struct exactly {

    tuple_t expected;

    exactly(tuple_t&& expected) : expected(expected) {}
    exactly(const tuple_t& expected) : expected(expected) {}

    template<class actual_tuple_t, class I = make_index_sequence<tuple_size<tuple_t>::value>>
    bool operator()(actual_tuple_t&& actual) const noexcept {
      return compare_tuples_detail(equals(), expected, forward<actual_tuple_t>(actual), I());
    }
  };

正如您可能已经猜到的那样,我希望将我的容器元素与名为expected的存储引用元素进行比较。

显然,我无法将exactly传递给boost::make_filter_iterator作为类型参数,因为它不是默认可构造的。而且我不知道如何将构造的类传递给它,就像嘿,我为你实例化它,只需调用它operator()

这是我使用它的地方:

  template<class predicate_t, class vector_t>
  decltype(auto) filter_impl(vector_t&& v) noexcept {

    auto good = boost::make_iterator_range(
      boost::make_filter_iterator<predicate_t>(begin(forward<vector_t>(v)), end(forward<vector_t>(v))),
      boost::make_filter_iterator<predicate_t>(end(forward<vector_t>(v)), end(forward<vector_t>(v)))
    );

    return remove_reference_t<vector_t>(good.begin(), good.end());
  };

1 个答案:

答案 0 :(得分:1)

好的,我找到了解决方案。 make_filter_iterator无法执行此操作,但filter_iterator有一个带谓词的构造函数

template <class Predicate, class Iterator>
class filter_iterator
{
 public:
    typedef iterator_traits<Iterator>::value_type value_type;
    typedef iterator_traits<Iterator>::reference reference;
    typedef iterator_traits<Iterator>::pointer pointer;
    typedef iterator_traits<Iterator>::difference_type difference_type;
    typedef /* see below */ iterator_category;

    filter_iterator();
    filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
    filter_iterator(Iterator x, Iterator end = Iterator());
    template<class OtherIterator>
    filter_iterator(
        filter_iterator<Predicate, OtherIterator> const& t
        , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
        );
    Predicate predicate() const;
    Iterator end() const;
    Iterator const& base() const;
    reference operator*() const;
    filter_iterator& operator++();
private:
    Predicate m_pred; // exposition only
    Iterator m_iter;  // exposition only
    Iterator m_end;   // exposition only
};

来自Boost文档。

所以我需要这样称呼它:

  template<class predicate_t, class vector_t>
  decltype(auto) filter_impl(predicate_t&& p, vector_t&& v) noexcept {

    auto good = boost::make_iterator_range(
      boost::filter_iterator<predicate_t, decltype(begin(forward<vector_t>(v)))>
        (forward<predicate_t>(p), begin(forward<vector_t>(v)), end(forward<vector_t>(v))),
      boost::filter_iterator<predicate_t, decltype(begin(forward<vector_t>(v)))>
        (forward<predicate_t>(p), end(forward<vector_t>(v)), end(forward<vector_t>(v)))
    );

    return remove_reference_t<vector_t>(good.begin(), good.end());
  };