4

少し苦労した後、ブーストfilter_iteratorのこの最小限の例をハックすることができました

using namespace std;
std::function<bool(uint32_t)> stlfunc= [](uint32_t n){return n%3==0;};
int main()
{
   vector<uint32_t> numbers{11,22,33,44,55,66,77,3,6,9};
   auto start = boost::make_filter_iterator(stlfunc, numbers.begin(), numbers.end());
   auto end   = boost::make_filter_iterator(stlfunc, numbers.end()  , numbers.end());
   auto elem  = std::max_element(start,end);
   cout << *elem;
}

それはうまく機能しますが、なぜmake_filter_iteratorがかかるのだろうかnumbers.end()? そのように使用するのは間違っているかもしれません.C配列の例から推測しました:
http://www.boost.org/doc/libs/1_53_0/libs/iterator/example/filter_iterator_example.cpp

4

2 に答える 2

8

それはドキュメントで説明されています:

要素をスキップする場合、フィルター アダプターは、基になる範囲の末尾を超えないように停止するタイミングを認識している必要があります。したがって、フィルター反復子は、通過するフィルター処理されていないシーケンス内の要素の範囲を示す反復子のペアで構成されます。

以下のソースから、最後に到達したかどうかを常にチェックすることができますsatisfy_predicate

void increment()
{
    ++(this->base_reference());
    satisfy_predicate();
}

void satisfy_predicate()
{
    while (this->base() != this->m_end && !this->m_predicate(*this->base()))
        ++(this->base_reference());
}

また、 Alex Chamberlainが指摘したように、コンストラクターは終了イテレーターを渡すときにオプションにします。たとえば、filter_iterator(Iterator x, Iterator end = Iterator());(デフォルトで構築可能である場合)。numbers.end()したがって、終了イテレータを構築するときにコードから省略できます。

于 2013-03-20T20:43:08.400 に答える
1

make_filter_iteratorテンプレートの宣言を見ると、次のようになっていることがわかります。

template <class Predicate, class Iterator>
filter_iterator<Predicate,Iterator>
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());

具体的には、最後のパラメーターがデフォルトのパラメーターであることがわかります。これは、デフォルトで構成されてIterator()いることを意味するように設定されており、一部のタイプのイテレーターでは、実際のend()イテレーターのように動作します。

ほとんどのコンテナタイプでは、実際のend()イテレータを渡す必要があります。

于 2013-03-20T20:45:04.530 に答える