Операции С++ в векторе struct

129
14

Я получаю ошибку "нет соответствия для оператора == 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-адреса из ранжирования на другой вектор строки, а затем используйте этот вектор строк в функции find, но когда я попытался сделать это, я не могу получить доступ к элементам в векторе ранжирования - например, rank [i].url не работает, и я не знаю, почему.. и помощь будет оценена.

спросил(а) 2011-12-26T21:51:00+04:00 9 лет, 9 месяцев назад
1
Решение
103

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

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

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

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

это будет работать с find

ответил(а) 2011-12-26T22:10:00+04:00 9 лет, 9 месяцев назад
91

Компилятор не знает, как сравнить объект типа 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

Существует несколько решений:


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

Важная точка:

Никогда не ставьте using namespace std; в файле заголовка.

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

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

ответил(а) 2011-12-26T22:08:00+04:00 9 лет, 9 месяцев назад
46

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

копировать ctor; оператор присваивания копии ('operator =') и, по крайней мере, operator== и operator<

ответил(а) 2011-12-26T22:09:00+04:00 9 лет, 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема