Search code examples
c++pointersvectorcountifbind2nd

Using an STL algorithm on vector of pointers of an object (C++)


I need to count the number of times an object of an array of pointers has the same name(member variable) as the parameter given to a member function. I have tried different approaches, but none of them worked. My code does not even compile. The error is: "error C2514: 'MyComparator' : class has no constructors" and here is the code of the class I use for the comparision and the function used for counting concurencies.

 //definition of the vector
 vector<Class1*> files;
 ...
 int Class2::countNames(string name)
    {
       return count_if(files.begin(), files.end(), bind2nd(MyComparator(),name));
    }
 ...
class MyComparator{
public:
 bool operator()(const CFileType*& ob1, const string &str)
 {
   return ob1->getName()==str;
 }
};

I am struggling with this for hours and I want to do it using STL. The catch here is that i have an vector of pointers, if I had a normal vector it would not need a predicate function, in my case I have to give a parameter to it and I think bind2nd() is the right way. Any help would be greatly appreciated!


Solution

  • Under C++11, you could use a lambda expression, which is much easier than the archaic bind2nd. For example:

    #include <string>
    #include <vector>
    #include <algorithm>
    #include <iostream>
    
    class Class1 {
    public:
        Class1(const std::string& name) : Name(name) {
        }
        const std::string& getName() const {
            return Name;
        }
    private:
        std::string Name;
    };
    
    size_t CountMatchingNames(const std::vector<Class1*>& v, const std::string& name) {
        return std::count_if(
            v.begin(),
            v.end(),
            [&name](Class1* c1) { return name == c1->getName(); }
        );
    }
    
    int main() {
    
        Class1 rob("rob");
        Class1 bob("bob");
        Class1 mitch("mitch");
    
        std::vector<Class1*> v;
        v.push_back(&bob);
        v.push_back(&mitch);
        v.push_back(&rob);
        v.push_back(&mitch);
        v.push_back(&bob);
        v.push_back(&bob);
    
        std::cout << "rob count:\t" << CountMatchingNames(v, "rob") << std::endl;
        std::cout << "bob count:\t" << CountMatchingNames(v, "bob") << std::endl;
        std::cout << "mitch count:\t" << CountMatchingNames(v, "mitch") << std::endl;
    
        return EXIT_SUCCESS;
    
    }
    

    This prints:

    rob count:      1
    bob count:      3
    mitch count:    2