C ++ операции над вектором структуры - PullRequest
0 голосов
/ 26 декабря 2011

Я получаю ошибку "нет совпадения для оператора == in__first. Вот код:

заголовочный файл:

#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);
};

И исходный файл:

#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;
}

Я попытался прокомментировать некоторые блоки кода в исходном файле, и строка с функцией find (), похоже, выдает ошибки. Это функция из алгоритма класса, используемая для проверки того, содержит ли вектор определенный элемент. Я обнаружил, что это неправильно, потому что я пытаюсь сравнить struct со строкой в ​​функции find. Я могу справиться с этим, скопировав URL из ранжирования в другой вектор строки, а затем использовать этот вектор строк в функции поиска, но когда я попытался это сделать, я не могу получить доступ к элементам в векторе 'ранжирование' - например, ранжированию .url не работает, и я не знаю почему .. и помощь будет принята.

Ответы [ 3 ]

4 голосов
/ 26 декабря 2011
find(ranking.begin(), ranking.end(), rElement.url)

вы предлагаете найти для поиска rElement.url (который имеет тип string) в [ranking.begin(), ranking.end()) (который имеет элементы типа rankingElements).Если явно не дать std::find функцию сравнения, он пытается использовать operator== для сравнения элементов с искомыми элементами.Поэтому он пытается вызвать operator==(rankingElement, string), которого, очевидно, не существует.По моему мнению, лучший способ сделать что-то подобное - использовать 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() )

в противном случае вы можете написать operator==:

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

работа с find

3 голосов
/ 26 декабря 2011

Компилятор не знает, как сравнить объект типа rankingElement с объектом типа string (это то, что радует в std :: find).

В 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

Есть несколько решений:

  1. Предоставить соответствующую функцию сравнения
    • bool operator==(rankingElement const& lhs, std::string const& rhs)
  2. Используйте версию find, которая позволяет передавать функцию / функтор
    • std::find_if(ranking.begin(), ranking.end(), test_Ranking_against_url)

Важный момент:

  1. Никогда положить using namespace std; в заголовочный файл.

  2. Вы можете поместить его using namespace std; в исходный файл.
    Но я бы даже не одобрял это.
    Предпочитаю использовать длинную форму всех членов std. (т.е.. std :: vector (не vector)).

  3. Передайте по ссылке любые крупные объекты (например, векторы).
    Используйте константную ссылку, если вы не хотите, чтобы оригинал изменился.
    Тогда вы не несете затрат на операцию копирования.

0 голосов
/ 26 декабря 2011

Когда вы используете типы UDF в качестве типов контейнеров STL, прежде чем вы должны предоставить действительные:

  1. copy ctor;
  2. оператор копирования ((operator = ')
  3. и не менее operator== и operator<
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...