在 class 个对象的向量中找到一个值

find a value in a vector of class objects

我写了一个基于class的向量:

class A {

private:

    string b;

    string c;

public:

    A(string n, string l) { b = l ;c = n; }

    struct Finder {

         Finder(std::string const& n) : name(n) { }  

         bool operator () ( const A & el) const  { return el.b == name; }

    private:

         std::string name;

    };

};


int main()

{

    vector<A> a1;

    a1.push_back(A("AA","aa"));

    a1.push_back(A("BB","bb"));

    a1.push_back(A("CC","cc"));

    a1.push_back(A("DD","dd"));


    vector<string>::iterator it;

    it = find_if(a1.begin(), a1.end(), A::Finder("CC"));

    if (it != a1.end()) {

        auto pos = it - a1.begin();

        cout << "CC is found at " << pos ;

    }
}

现在,我想在 a1 中搜索一个值。假设我想找到 "CC" 发生的元素的索引。

我找到了这些类似的解决方案:

Search a vector of objects by object attribute

std::find Object by Member

How can I find an object in a vector based on class properties?

How to find an object with specific field values in a std::set?

当我执行本节中的所有注释时,我仍然遇到错误!我错过了什么?我想问题在于定义 vector::iterator 它;

error C2679: 二进制“=”: 没有找到接受 'std::_Vector_iterator<_Myvec>' 类型右手操作数的运算符(或者没有可接受的转换)

并且

error C2678: 二进制“!=”: 未找到采用 'std::_Vector_iterator<_Myvec>' 类型左操作数的运算符(或没有可接受的转换)

  1. 要使用 Predicate,您需要使用 std::find_if,而不是 std::find

    it = std::find_if(a1.begin(), a1.end(), A::Finder("CC"));
    
  2. Finder::operator()的参数类型中使用const&

    而不是

    bool operator () (A & el) { return el.b == name; }
    

    使用

    bool operator () (A const& el) { return el.b == name; }
    

    UnaryPredicate的要求之一是(来自http://en.cppreference.com/w/cpp/concept/Predicate

    The function object pred shall not apply any non-constant function through the dereferenced iterator.

    许多编译器认为参数类型必须是值或 const&.

你必须使用标准算法std::find_if

it = find_if(a1.begin(), a1.end(), A::Finder("CC"));

考虑到内部类应该这样定义

struct Finder {

    Finder(std::string const& n) : name(n) { }  

    bool operator () ( const A & el) const  { return el.b == name; }

private:

    std::string name;

};

针对我的问题,我找到了两个解决方案:

  1. 您可以在 c++ 中基于向量 class 的对象中实现 std::find:

    class A {
        private:
           string b;
           string c;
        public:
        A(string i) : b(i) {}
        A(string n, string l) { b = n ;c = l; }
        string Getb(){ return b; }
        string Getc(){ return c; }
        bool operator==(const A & obj2) const
        {
           return (this->b.compare(obj2.b) == 0); 
        }
    };
    
    
    int main()
    {
       vector<A> a1;
       a1.push_back(A("AA","aa"));
       a1.push_back(A("BB","bb"));
       a1.push_back(A("CC","cc"));
       a1.push_back(A("DD","dd"));
    
       auto it = find(a1.begin(), a1.end(), A("CC"));
       if (it != a1.end()) {
          auto idx = distance(a1.begin(), it);
          cout << "b= " << it->Getb() << " c= " << it->Getc() << endl;
          cout << "Index= " << idx << endl;
        } else
          cout << "CC is not found" << endl;
    return 0;
    }
    
  2. 您可以在 c++ 中基于向量 class/structure 的对象中实现 std::find_if(感谢莫斯科的 @Vlad 和 @R Sahu):

    class A {
        private:
            string b;
            string c;
        public:
            A(string n, string l) { b = n ;c = l; }
            string Getb(){ return b; }
            string Getc(){ return c; }
            struct Finder {
                Finder(string const & n) : name(n) { }  
                bool operator () (const A & el) const { 
                     return el.Pos == name; 
                 }
                string name;
            };
     };
    
    
    int main()
     {
         vector<A> a1;
         a1.push_back(A("AA","aa"));
         a1.push_back(A("BB","bb"));
         a1.push_back(A("CC","cc"));
         a1.push_back(A("DD","dd"));
    
         vector<A>::iterator it;
         it = find_if(a1.begin(), a1.end(), A::Finder ("CC"));
         if (it != a1.end()) {
             auto idx = distance(a1.begin(), it);
             cout << "b= " << it->Getb() << " c= " << it->Getc() << endl;
             cout << "Index= " << idx << endl;
         } else
             cout << "CC is not found" << endl;
    
      return 0;
     }