You understand it pretty well.
struct initial: public std::unary_function <Container, bool>
std::unary_function is a template class (in <functional>) that provides information about its types so that it can be used with the standard algorithms (in this case,
count_if()).
In this case,
initial::argument_type is the
Container's type, and
initial::result_type is
bool.
This tells us that the object functor takes a 'Container' as argument and returns bool, which is what a predicate does.
typedef typename Container::value_type value_type;
In this case I just did it to relieve having to type a lot, but it also creates a new type:
initial::value_type, which is the same as the container's elements' type.
As to why I did this, you need to think about the types of things being used.
The
count_if() takes an iterator to a container (
vector) and passes the vector's elements (
strings) to the
initial() object, which returns
true if the element is to be counted.
Inside the
initial() object, we don't know or care what the outermost container's type is (
vector), as we never see or handle it. What we do require, though, is that the predicate argument type is itself some form of container (
string). We are interested if the argument container (
string) begins with a specific element, whose type is
Container::value_type (
string::value_type).
In short, a
vector <string <char> > is first iterated over its strings with the count_if() algorithm, and each string's first character is tested against a given value:
initial( const value_type& value ): value( value ) { }
We want to be able to specify which value is to be used to test against with each string.
bool operator () ( const Container& container ) const
Always make your functions
const if they don't modify the object. No other reason.
return *(container.begin()) == value;
Yes, but I could also have written it other ways:
return container.at( 0 ) == value; |
return container[ 0 ] == value; |
are also valid. I suppose the last would be most optimal, but the second is the safest. (I forgot to check if the container is empty.)
I'm glad you all are picking this up so well. The STL is very cool, and makes life easier in a lot of ways.
:-)