【问题标题】:find a value in a vector of class objects在类对象的向量中找到一个值
【发布时间】:2015-10-02 05:46:31
【问题描述】:

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

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?

当我实现本节中的所有 cmets 时,我仍然得到错误!我错过了什么?我想问题在于定义 vector::iterator it;

错误 C2679:二进制“=”:未找到采用“std::_Vector_iterator<_myvec>”类型右侧操作数的运算符(或没有可接受的转换)

和,

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

【问题讨论】:

  • 在发布错误消息时,您应该真正指出编译器指向的行,否则我们必须猜测。
  • std::[multi]map&lt;std::string, std::string&gt; 在这里不是更有意义吗?

标签: c++ class object vector find


【解决方案1】:

我为我的问题找到了两个解决方案:

  1. 您可以在 c++ 中在基于向量类的对象中实现 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++ 中在基于向量类/结构的对象中实现 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;
     }
    

【讨论】:

    【解决方案2】:
    1. 要使用Predicate,您需要使用std::find_if,而不是std::find

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

      代替

      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

      函数对象 pred 不应通过解引用的迭代器应用任何非常量函数。

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

    【讨论】:

    • 投了赞成票。通过不传递引用,每次都会创建一个副本。
    【解决方案3】:

    你必须使用标准算法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;
    
    };
    

    【讨论】:

    • @Vlad 来自莫斯科,@R Sahu:我修改了我的代码(如上),但是我仍然遇到同样的错误!你知道出了什么问题吗?
    • @Vlad 来自莫斯科,@R Sahu:我终于找到了解决问题的方法。感谢您的大力帮助。
    • @Afrand 看来您的数据成员初始化顺序错误,而不是 A( std::string n, std::string l ) { b = l ;c = n; } 应该有 A( std::string n, std::string l ) { b = n ;c = l; } 即 b 应由 n 初始化。并声明像 const A & 这样的参数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多