简体   繁体   English

对struct向量的C ++操作

[英]C++ operations on vector of struct

I am getting error "no match for operator==in__first. Here is the code: 我收到错误消息“操作符== in__first不匹配。这是代码:

header file: 头文件:

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>

using namespace std;

struct rankingElement {
   string url;
   int rank;
};

class RankingCreator {
public:
   static const int MAX_QUERY_SIZE = 20;
   RankingCreator();
   virtual ~RankingCreator();
   bool checkPageRank(rankingElement rElement, vector<rankingElement> ranking);
   void insertIntoRanking(rankingElement rElement);
};

And source file : 和源文件:

#include "RankingCreator.h"

bool RankingCreator::checkPageRank(rankingElement rElement,
                                   vector<rankingElement> ranking)
{
   if (ranking.size() < MAX_QUERY_SIZE) {
      // enough space for another page in ranking
      return true;
   } else {
      if (find(ranking.begin(), ranking.end(), rElement.url) != ranking.end()) {
         // url is already in ranking
         return false;
      } else {

      }
   }
   return true;
}

I tried commenting some blocks of code in source file and the line with find() function seems to generate the errors. 我尝试注释源文件中的某些代码块,而find()函数的行似乎会生成错误。 It is function from class algorithm used to check whether a vector already contains certain element. 它是来自类算法的函数,用于检查向量是否已包含某些元素。 I found out that it is wrong, because I try to compare struct with string in find function. 我发现这是错误的,因为我尝试在find函数中将struct与string进行比较。 I can handle that by copying urls from ranking to another vector of string and then use that vector of strings in find function, but when I tried to do that I can't access elements in 'ranking' vector - for instance ranking[i].url doesn't work and I don't know why.. and help would be appreciated. 我可以通过将网址从排名复制到另一个字符串向量,然后在find函数中使用该字符串向量来解决此问题,但是当我尝试这样做时,我无法访问“排名”向量中的元素-例如rank [i] .url不起作用,我也不知道为什么..并且帮助将不胜感激。

find(ranking.begin(), ranking.end(), rElement.url)

you are telling find to search for rElement.url (which is of type string ) in [ranking.begin(), ranking.end()) (which has elements of type rankingElements ). 您要告诉find在[ranking.begin(), ranking.end()) (具有类型元素rankingElements )中搜索rElement.urlstring类型)。 When not explicitely giving std::find a comparison function it tries to use operator== to compare the elements with the searched for elements. 当未明确给std::find提供比较功能时,它将尝试使用operator==将元素与搜索到的元素进行比较。 So it tries to invoke operator==(rankingElement, string) which obviously doesn't exist. 因此,它尝试调用显然不存在的operator==(rankingElement, string) Imo the best way to make something like that work is to use find_if which accepts a predicate: Imo进行类似工作的最佳方法是使用find_if ,它接受一个谓词:

struct functor  {
    string url;
    functor(const string& str):url(str){}
    bool operator()(const rankingElement& val) { return val.url == this->url; }
};
...
if(find_if(ranking.begin(), ranking.end(), functor(rElement.url)) != ranking.end() )

otherwise you can write an operator== : 否则,您可以写一个operator==

bool operator==(const rankingElement& elem, const string& url) 
{ return elem.url == url; }

this will work with find 这将与find工作

There is no way the compiler knows how to compare an object of type rankingElement with an object of type string (this is what is happeneing in std::find). 编译器无法知道如何将rankingElement类型的对象与string类型的对象进行比较(这就是std :: find中发生的事情)。

In the std::find you are doing the test: 在std :: find中,您正在执行测试:

find(ranking.begin(), ranking.end(), rElement.url)

// Inside this you are iterating through a vector of `rankingElement`
// But the element you ae testing against is: `rElement.url` which is a std::string


// Sort of like this:
ranking[0] == rElement.url
              ^^^^^^^^^^^^  Object of type string
^^^^^^^^^^ Object of type rankingElement

There are a couple of solutions: 有两种解决方案:

  1. Provide an appropriate compare function 提供适当的比较功能
    • bool operator==(rankingElement const& lhs, std::string const& rhs)
  2. Use the version of find that allows you to pass a function/functor 使用find版本,该版本允许您传递函数/函数
    • std::find_if(ranking.begin(), ranking.end(), test_Ranking_against_url)

Important Point: 很重要的一点:

  1. Never put using namespace std; 永远不要 using namespace std; in the header file. 在头文件中。

  2. You can put it using namespace std; 您可以using namespace std;来放置它using namespace std; the source file. 源文件。
    But I would even discourage that. 但是我什至不鼓励这样做。
    Prefer to use the long form of all members of std. 最好使用std所有成员的长格式。 (ie. std::vector (not vector)). (即std :: vector(不是vector))。

  3. Pass by reference any large objects (like vectors). 通过引用传递任何大对象(如矢量)。
    Use const reference if you don't want the original changed. 如果您不想更改原始内容,请使用const reference。
    Then you don't incur the cost of a copy operation. 这样就不会产生复制操作的费用。

When you use UDF types as the types of STL containers you must before provide valid: 当您将UDF类型用作STL容器的类型时,必须提供有效的信息:

  1. copy ctor; 复制ctor;
  2. copy assignment operator ('operator=') 复制分配运算符('operator =')
  3. and at least operator== and operator< 至少是operator==operator<

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM