Jump to content
  • Advertisement
Sign in to follow this  
3dcgmodeling

count_if

This topic is 4258 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

template<class InputIterator, class Predicate> inline size_t count_if(InputIterator first, InputIterator last, Predicate P)
#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include <vector>
using namespace std;

// Return true if string str starts with letter 'S'
int MatchFirstChar( const string& str)
{
    string s("S") ;
    return s == str.substr(0,1) ;
}

void main()
{
    const int VECTOR_SIZE = 8 ;

    // Define a template class vector of strings
    typedef vector<string, allocator<string> > StringVector ;

    //Define an iterator for template class vector of strings
    typedef StringVector::iterator StringVectorIt ;

    StringVector NamesVect(VECTOR_SIZE) ;   //vector containing names

    StringVectorIt start, end, it ;

    int result = 0 ;   // stores count of elements
                       // that match value.

    // Initialize vector NamesVect
    NamesVect[0] = "She" ;
    NamesVect[1] = "Sells" ;
    NamesVect[2] = "Sea" ;
    NamesVect[3] = "Shells" ;
    NamesVect[4] = "by" ;
    NamesVect[5] = "the" ;
    NamesVect[6] = "Sea" ;
    NamesVect[7] = "Shore" ;

    start = NamesVect.begin() ;   // location of first
                                  // element of NamesVect

    end = NamesVect.end() ;       // one past the location
                                  // last element of NamesVect

    // print content of NamesVect
    cout << "NamesVect { " ;
    for(it = start; it != end; it++)
        cout << *it << " " ;
    cout << " }\n" << endl ;

    // Count the number of elements in the range [first, last +1)
    // that start with letter 'S'
    result = count_if(start, end, MatchFirstChar) ;

    // print the count of elements that start with letter 'S'
    cout << "Number of elements that start with letter \"S\" = "
        << result << endl  ;
}
		

count_if take 3 parameter,3rd is a class,the above code pass in a fucntion address.is a function name(address) equal to class ? no parameter pass to the function MatchFirstChar, where is the function parameter ?

Share this post


Link to post
Share on other sites
Advertisement
Third parameter is not a class, it's an object (instance of a class for example) which overloads the function call operator. Every object in the range is passed to the object, and it counts how many times the call returned true.

What you pass is a function pointer, which can be called as a function. You're not calling the function, you're just passing the pointer to it so count_if can call it.

Share this post


Link to post
Share on other sites
What you need to pass is anything that can be used as a Predicate. Pointers to (free, not member) functions qualify, and it is also possible to use instances of a class, if that class has an overload for 'operator()' with the correct signature. This operator() is a special operator designed to let you treat an instance as if it were a function.

In our case, we could replace the function MatchFirstChar with a class instance as follows:


class first_char_matcher {
bool operator() (const string& str) {
// By the way, you should use the type 'bool' when that is what you mean.
// In C++, bool is a *real* type, and not some kind of wrapper for ints.
string s("S");
return s == str.substr(0,1);
}
};

first_char_matcher MatchFirstChar;

// Rest of code is the same



Now 'MatchFirstChar' will be the class instance, and it will repeately have its operator() called. Of course, this is only an example; normally when you use a class like this, you will create an instance of it locally:


// Remove the global instance, and instead call count_if like this:
result = count_if(start, end, first_char_matcher());


The () here are because we are calling the constructor, to get an unnamed instance of the class.




As for the arguments, you don't write anything in for that; what count_if does is iterate over the range, and call the function using each element of the range. It might be implemented something like this:


template<class InputIterator, class Predicate> inline
size_t count_if(InputIterator first, InputIterator last,
Predicate P) {
size_t result = 0;
for (InputIterator current = first; current != last; ++current) {
if (P(*current)) { result += 1; }
}
return result;
}


See how P is 'called', with ()'s. Because of the templates, we can use any type for P where that syntax will work - so function pointers work (because it just calls the function) and the class instances work (because of the meaning of operator()).

Share this post


Link to post
Share on other sites
I am curious the 3rd parameter is object, but how does it pass compiler without error when you pass a function pointer to it. because function pointer is a class instance right?

Share this post


Link to post
Share on other sites
Quote:
I am curious the 3rd parameter is object, but how does it pass compiler without error when you pass a function pointer to it. because function pointer is a class instance right?


Zahlman already explained this but once again:

A function pointer most certainly is not a class instance, the third paramater doesnt have to be a class instance it only needs to "behave like a function" i.e. it only needs to be something that you can call like its a function.

Edit: if your getting confused by the "class" in the template decleration then:

The class in the template decleration doesnt mean that the thing has to be a class it is equivelent to using typename and just represets a template paramater that is a type as opposed to say a std::size_t in a vector<n>.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!