{"id":3783,"date":"2010-08-09T17:26:00","date_gmt":"2010-08-09T17:26:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2010\/08\/09\/the-filterator\/"},"modified":"2019-02-18T18:45:28","modified_gmt":"2019-02-18T18:45:28","slug":"the-filterator","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/the-filterator\/","title":{"rendered":"The Filterator"},"content":{"rendered":"<p class=\"MsoNormal\"><span style=\"font-family: 'Verdana','sans-serif';font-size: 12pt\">My name is Ahmed Charles and I currently work on Windows Error Reporting. &nbsp;I believe that this is the first time that someone not on the VC team has written a blog, but I hope you will find it useful anyways. &nbsp;I&rsquo;d like to thank Stephan T. Lavavej for the idea and valuable feedback while writing it.&nbsp; And we both owe the idea for the iterator to Boost.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: 'Verdana','sans-serif';font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: 'Verdana','sans-serif';font-size: 12pt\">A common question from programmers who have an intermediate amount of experience with using the STL is, &#8220;How do I write an STL iterator?&#8221;.&nbsp; Writing an STL iterator is not especially difficult &ndash; it just requires some care.&nbsp; STL iterators must satisfy a number of requirements (given by section 24.2 of the (soon to be) International Standard for C++, draft at <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2010\/n3092.pdf\">http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2010\/n3092.pdf<\/a>), and the code to do so takes roughly 150 editor lines.&nbsp; Figuring out the code from the requirements can be overwhelming, but once you see the code, it&#8217;s easy.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: 'Verdana','sans-serif';font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: 'Verdana','sans-serif';font-size: 12pt\">Therefore, I&#8217;ve written an example STL iterator, whose purpose in life is to wrap an existing iterator and filter the elements based on a supplied predicate, which I&#8217;ve imaginatively called Filterator (in homage to the Mallocator).&nbsp; I&#8217;ve carefully implemented all of the checks that would be required in real production code.&nbsp; And I&#8217;ve exhaustively commented the various parts of the iterator to aid in determining which portions should be changed when implementing other iterators.&nbsp; Hopefully, this should demystify the implementation of STL iterators:<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: 'Verdana','sans-serif';font-size: 12pt\"><\/span><\/p>\n<p><span style=\"font-family: 'Verdana','sans-serif';font-size: 12pt\"><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">C:Temp&gt;type filterator.cpp<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">\/\/ The following headers are required for all iterators.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">#include &lt;iterator&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Required for iterator_traits<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">\/\/ The following headers contain stuff that filterator uses.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">#include &lt;type_traits&gt; \/\/ Required for std::conditional\/<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ is_same\/is_convertible<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">#include &lt;memory&gt;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ For std::addressof<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">\/\/ The following headers contain stuff that main() uses.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">#include &lt;algorithm&gt;<span>&nbsp;&nbsp; <\/span>\/\/ For std::fill<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">#include &lt;iostream&gt;<span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ For std::cout<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">#include &lt;ostream&gt;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ For std::endl<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">#include &lt;string&gt;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ For std::string<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">#include &lt;vector&gt;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ For std::vector<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">template &lt;class Iterator, class Predicate&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">class filterator {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\">public:<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Required to access private members in the converting<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ constructor because different instantiations of a<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ template are different classes without special access<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ rights to each other.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>template &lt;class OtherIterator, class OtherPredicate&gt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>friend class filterator;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Define iterator_category to be the iterator category<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ of the Iterator used, unless it is a random access<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ iterator, which cannot provide constant time<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ functions for random access operators because of<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ needing to test the predicate.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>typedef typename std::iterator_traits&lt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Iterator&gt;::iterator_category underlying_category;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>typedef typename std::conditional&lt;std::is_same&lt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>underlying_category,<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>std::random_access_iterator_tag<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&gt;::value,<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>std::bidirectional_iterator_tag,<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>underlying_category&gt;::type iterator_category;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Define the other typedefs required by iterators.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>typedef typename std::iterator_traits&lt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Iterator&gt;::value_type value_type;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>typedef typename std::iterator_traits&lt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Iterator&gt;::reference reference;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>typedef typename std::iterator_traits&lt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Iterator&gt;::pointer pointer;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>typedef typename std::iterator_traits&lt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Iterator&gt;::difference_type difference_type;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Default constructor which value-initializes all of<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ the members.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>filterator() : m_iter(), m_end(), m_pred() {}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Constructs a filterator from all possible parameters.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ pred may be default constructed, as well.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>filterator(Iterator begin, Iterator end,<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Predicate pred = Predicate())<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;<\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: m_iter(begin), m_end(end), m_pred(pred) {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>validate_predicate();<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Converting constructor which can be used to convert<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ iterators into const_iterators.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>template &lt;class OtherIterator&gt; filterator(<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>const filterator&lt;OtherIterator, Predicate&gt;&amp; f,<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>typename std::enable_if&lt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>std::is_convertible&lt;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>OtherIterator, Iterator<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&gt;::value&gt;::type * = nullptr)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: m_iter(f.m_iter),<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>m_end(f.m_end),<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>m_pred(f.m_pred) {}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Returns a copy of the predicate for this filterator.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>Predicate predicate() const {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>return m_pred;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Returns a copy of a filterator representing the end<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ of this sequence.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>filterator end() const {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>return filterator(m_end, m_end, m_pred);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Returns a copy of the end iterator for this<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ filterator.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>Iterator base_end() const {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>return m_end;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Returns a copy of the iterator which represents the<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ current position.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>Iterator base() const {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>return m_iter;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Dereferences this iterator<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>reference operator*() const {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>return *m_iter;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Dereferences this iterator<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>pointer operator-&gt;() const {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&nbsp;<\/span>return std::addressof(*m_iter);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Pre-increment operator which checks the predicate<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ before stopping.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>filterator&amp; operator++() {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>++m_iter;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>validate_predicate();<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>return *this;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Post-increment operator which checks the predicate<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ before stopping.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>filterator operator++(int) {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>filterator temp(*this);<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>++*this;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>return temp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ Pre-decrement operator which checks the predicate<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>\/\/ before stopping.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>filterator&amp; operator&#8211;() {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8211;m_iter;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ note that we don&#8217;t store a begin iterator to<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ check for passing the beginning of the sequence,<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ unlike the end. This is because decrementing the<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ first iterator is undefined and applying a filter<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ on top of the underlying iterator doesn&#8217;t change<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>\/\/ this, even if the resulting sequence is empty.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>while (!m_pred(*m_iter)) &#8211;m_iter;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>return *this;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12pt\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\" style=\"margin: 0in 0in 0pt\"><span style=\"font-family: Consolas;font-size: 12\"><\/span><\/p>\n<p><\/span><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>My name is Ahmed Charles and I currently work on Windows Error Reporting. &nbsp;I believe that this is the first time that someone not on the VC team has written a blog, but I hope you will find it useful anyways. &nbsp;I&rsquo;d like to thank Stephan T. Lavavej for the idea and valuable feedback while [&hellip;]<\/p>\n","protected":false},"author":289,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,32],"class_list":["post-3783","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-dev","tag-stl"],"acf":[],"blog_post_summary":"<p>My name is Ahmed Charles and I currently work on Windows Error Reporting. &nbsp;I believe that this is the first time that someone not on the VC team has written a blog, but I hope you will find it useful anyways. &nbsp;I&rsquo;d like to thank Stephan T. Lavavej for the idea and valuable feedback while [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3783","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/289"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=3783"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/3783\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=3783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=3783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=3783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}