/******************************************************************************/
/* */
/* FILE: december.cpp */
/* */
/* Slowly, I begin to appreciate the STL */
/* ===================================== */
/* */
/* Compiled and tested with Visual C++ V6.0 */
/* */
/* V1.00 19-DEC-2000 P. Tellenbach http://www.heimetli.ch/ */
/* */
/******************************************************************************/
#include <iostream>
#include <algorithm>
class Process
{
public:
operator()( char ch )
{
std::cout.put( ch ) ;
}
operator int()
{
return 0 ;
}
} ;
int main()
{
char *ps = "Hello world !\n" ;
return std::for_each( ps, std::find(ps,(char *)0,'\0'), Process() ) ;
}
Update 19. December 2020
The compiler complained about operator() without a return type. Declaring the method as void corrected the problem.
The warnings about const and non-const were also easy to fix.
But then the program printed a lot of nonsense and crashed!
This turned out to be a consequence of an optimization in the implementation of the find-algorithm in the library. The function checks the iterator-type and calls a different version for random access iterators. This version determines the distance between the iterators and tries to partially unroll the loop. The nullptr passed as end of the sequence produces a negative number and that produces an incorrect result.
This could be solved by adding a large number to the pointer, but I decided to use a custom iterator which identifies itself as an input-iterator.
/******************************************************************************/
/* */
/* FILE: december.cpp */
/* */
/* Slowly, I begin to appreciate the STL */
/* ===================================== */
/* */
/* Compiled and tested with Visual C++ V6.0 */
/* */
/* V1.00 19-DEC-2000 P. Tellenbach http://www.heimetli.ch/ */
/* */
/* Compiled and tested with g++ V8.3.0 */
/* */
/* V2.00 19-DEC-2020 P. Tellenbach https://www.heimetli.ch/ */
/* */
/******************************************************************************/
#include <iostream>
#include <algorithm>
#include <iterator>
class CharIterator : public std::iterator<std::input_iterator_tag, char>
{
const char* ptr;
public:
CharIterator( const char* p ) : ptr( p )
{
}
CharIterator( const CharIterator &it ) : ptr( it.ptr )
{
}
CharIterator& operator++()
{
++ptr ;
return *this ;
}
CharIterator operator++(int)
{
CharIterator tmp(*this) ;
operator++() ;
return tmp;
}
bool operator==(const CharIterator& rhs) const
{
return ptr == rhs.ptr ;
}
bool operator!=(const CharIterator& rhs) const
{
return ptr != rhs.ptr ;
}
const char& operator*()
{
return *ptr ;
}
};
class Process
{
public:
void operator()( char ch )
{
std::cout.put( ch ) ;
}
operator int()
{
return 0 ;
}
} ;
int main()
{
const char *ps = "Hello world !\n" ;
return std::for_each( CharIterator(ps), std::find(CharIterator(ps),CharIterator(nullptr),'\0'), Process() ) ;
}