why does std::search need forward iters
my issue is identical to the thread below, I'm struggling to understand the answers given, or rather my code shouldn't开发者_开发知识库 work as it only uses input iterators ..but my func appears to work and behave identically to std::search ..so I'm at a loss and loathe to move on without understanding properly ...maybe if someone can suggest an input that will break my function but not the std::
From Why do I need a Forward Iterator to implement my customized std::search :
I am studying the book "Accelerated C++" from Koenig & Moo.
Exercise 8-2 ask me to implement on my own some templatized functions from <algorithm> and <numeric>, and to specify what kind of iterator does my implementation require.
When trying to implement std::search, I determined that I need only "input" iterators.
However, looking at the implementation of std::search installed with my compiler, I can see that they use "forward" iterators, but I cannot understand why, because there is no need to write, only to read, and input iterators meet the requirement.
Can anybody here help me to understand this, please? Why would I need to use "forward" iterators to implement std::search?
Thanks in advance.
myfunction:
template <class In>
In search( In begin, In end, In begin2, In end2 )
{
In found ; // iter: 1st element in pattern match(in content)
In pattern_begin = begin2 ; // iter: 1st element in search pattern.
int flag = 0 ; // flag: partial match found?
// search content for pattern
while ( begin < end ) {
// if pattern-match fails ..reset vars
// & continue searching remaining content/elements
if ( *begin != *begin2 ) {
In ret ;
begin2 = pattern_begin ;
flag = 0 ;
begin++ ;
} else {
// compare next element in pattern with next element in content.
// if: 1st element of 'pattern' is found, store iter to it's pos
// ..then if entire pattern is found, we can ret an iter to where it starts
if ( flag == 0 ) {
found = begin ;
flag = 1 ;
}
// inc iters to compare next elements in partial match
begin++ ;
begin2++ ;
}
// if: iter is 1-past end of search pattern
// then entire pattern has been found
// return the iter to where it starts
if( begin2 == end2 ) { return found ; }
}
// end of content reached, no complete pattern found
// begin should? equal an iter 1-past the end of content
return begin ;
}
driver:
///* // Driver: custom::search( b, e, b2, e2 )
#include <string>
#include <vector>
#include <iostream>
//#include <algorithm>
#include "library_algorithms.h"
int main() {
// init string test
std::string content = "fo The fox foxu jumped foxe foxy " ;
std::string search_pattern = "foxy" ;
// func test on string
std::string::iterator ret_iter =
custom::search( content.begin(), content.end(), search_pattern.begin(), search_pattern.end() ) ;
//std::search( content.begin(), content.end(), search_pattern.begin(), search_pattern.end() ) ;
// output
if ( ret_iter != content.end() ) {
std::cout << std::endl << std::endl << search_pattern << ": found at position: " << int( ret_iter - content.begin() ) << std::endl;
} else {
std::cout << std::endl << std::endl << search_pattern << ": ...not found" << std::endl;
}
// Init vec test:
// create content values in range: 10 20 30 <......> 9970 9980 9990
std::vector<int> myvector;
for (int i=1; i<1000; i++) myvector.push_back(i*10);
// create pattern values to search for
std::vector<int> pattern ;
pattern.push_back( 3730 ) ;
pattern.push_back( 3740 ) ;
pattern.push_back( 3750 ) ;
pattern.push_back( 3760 ) ;
// test: func on vector<int>
std::vector<int>::iterator it;
it = custom::search ( myvector.begin(), myvector.end(), pattern.begin(), pattern.end() );
// output
if (it!=myvector.end())
std::cout << std::endl << std::endl << "pattern found at position " << int(it-myvector.begin()) << std::endl;
else
std::cout << std::endl << std::endl << "pattern not found" << std::endl;
return 0 ;
}
You've misunderstood what an input iterator can do.
You can't "save" or copy an input iterator. It allows you to traverse the sequence exactly once. In other words, this line, among others, will break: begin2 = pattern_begin
.
An input iterator may represents something that you can't readily "rewind", like, say, the stream of data received from a network adapter. An iterator pointing to "6 elements ago" is no longer meaningful, because that data may no longer be available in memory. You only have the current position in the stream.
It should be obvious that in order to implement search
correctly, you need to be able to traverse parts of the sequence more than once.
精彩评论