Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have written a program to get the reference count of an object from vector. I am storing the objects in list with there count from vector. I dont want to store them in sorted order thats why I am using a list to store. but while compilation this failing with error

"‘Item’ is not derived from ‘const __gnu_cxx::__normal_iterator<_IteratorL, _Container>’". 

I am not sure about error. Dear friends, can you please answer me with below questions.

  • How to fix this error?
  • How I can use any container which will store them with theirs reference count but not in sorted order but their arrival order in vector? Please use below link to view source file.
  • #include <iostream>
    #include <string>
    #include <list>
    #include <vector>
    #include<bits/stdc++.h>
    using namespace std;
    class Item
        public:
        int count;
        string name;
        Item(){};
        Item(string str, int cnt)
            name = str;
            count = cnt;
    string func(vector<string>& vec)
        list<Item> lst;
        list<Item>:: iterator it;
        for(int i=0; i<vec.size(); i++)
            it = find(lst.begin(), lst.end(), vec[i]);
            if(it != lst.end())
                it->count++;
                lst.push_back({vec[i], 1});
        for(it = lst.begin(); it != lst.end(); it++)
            if(it->count == 1)
                return it->name;
        return "";
    int main()
        vector <string> vec = {"saint", "catacana", "saint", "ant"};
        cout<<"String is "<<func(vec);
        return 0;
                    The failing line is it = find(lst.begin(), lst.end(), vec[i]); -- you're trying to find a string in a list of Items, but the compiler has no idea how to compare a string to an item.
    – user14215102
                    Sep 6, 2021 at 6:43
                    This is what GCC says: error: no match for 'operator==' (operand types are 'Item' and 'const std::__cxx11::basic_string<char>'). This is what Clang says: error: invalid operands to binary expression ('Item' and 'const std::basic_string<char>').
    – Evg
                    Sep 6, 2021 at 6:45
                    Dratenik posted the correct answer. Couple more small things: first, consider using initializer lists for your constructors. Second, you don't need to define a default constructor if it does nothing. It is created by default (there exceptions but they do not apply to this case). And last, don't use global using namespace std
    – Sceptical Jule
                    Sep 6, 2021 at 7:02
    

    std::find fails because it tries to compare an Item to a std::string and there is no such == operator defined.

    you can solve this by adding the operator==(std::string) to the class Item:

    bool operator==(const std::string& name) const {
        return this->name == name;
    

    Now this will work, but it's not very clean. It adds code to the class Item and calling this function from anywhere else does not make a lot of sense. It also scales badly, imagine your Items have a lot more variables, you don't want to add a new function for every time you search for a new Items attribute.

    So that's why there is the generalized solution, std::find_if. It accepts a lamda. This allows you to fully specify the search process:

    for (int i = 0; i < vec.size(); i++)
        auto search = [&](const Item& item) { //the lambda
            return item.name == vec[i];
        it = find_if(lst.begin(), lst.end(), search); //pass to find_if
    
  • Read here why using namespace std; is considered bad practice and here why <bits/stdc++.h> is to be avoided.
  • Dear friends, thanks for your valuable reply. I was doing silly mistake as testing equality of item and string. – Jitendra Yadav Sep 7, 2021 at 13:14

    You are using find for different types, so get the missing operator compile errors. It can be fixed by use find_if with lambda as pred:

    it = find_if(lst.begin(), lst.end(), [&](const Item& item) { return vec[i] == item.name; });
    

    Or add the missing operator==

    bool operator==(const Item& lhs, const std::string& rhs) {
      return lhs.name == rhs;
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.