Ошибка в std :: list :: sort с пользовательским компаратором (ожидаемое первичное выражение до маркера ')') - PullRequest
1 голос
/ 09 июля 2009

Заголовок - главный вопрос.Точный сценарий (я использую «namespace std;»):

void SubstringMiner::sortByOccurrence(list<Substring *> & substring_list) {
   list::sort(substring_list.begin(), substring_list.end(), Substring::OccurrenceComparator);
}

Это определение компаратора:

class Substring {
    // ...
    class OccurrenceComparator {
        public:
            bool operator() (Substring * a, Substring *b);
    }
};

Реализация компаратора интуитивно понятна и тривиальна.Я также использую очень похожий компаратор в std :: set, и он отлично работает.Когда я добавляю функцию sortByOccurrence (), она дает мне ошибку в заголовке.

Что мне делать?

РЕДАКТИРОВАТЬ: Я сейчас пытаюсь передать Substring:: OccurrenceComparator () в качестве компаратора, и я получаю следующую ошибку:

g++ -Wall -g -c substring_miner.cpp -o obj/subtring_miner.o
substring_miner.cpp: In function ‘void SubstringMiner::sortByOccurrence(std::list<Substring*, std::allocator<Substring*> >&)’:
substring_miner.cpp:113: error: no matching function for call to ‘std::list<Substring*, std::allocator<Substring*> >::sort(std::_List_iterator<Substring*>, std::_List_iterator<Substring*>, Substring::OccurrenceComparator)’
/usr/include/c++/4.3/bits/list.tcc:303: note: candidates are: void std::list<_Tp, _Alloc>::sort() [with _Tp = Substring*, _Alloc = std::allocator<Substring*>]
make: *** [substring_miner] Error 1

Моя строка кода теперь:

list<Substring *>::sort(substring_list.begin(), substring_list.end(), Substring::OccurrenceComparator());

Я не могу удалить шаблон, или он даетмне сообщают, что параметры шаблона были неверными.

Ответы [ 3 ]

4 голосов
/ 09 июля 2009

list member sort является нестатической функцией, поэтому ее необходимо вызывать для экземпляра списка.

substring_list.sort( Substring::OccurrenceComparator() );

Редактировать: Вы не можете использовать бесплатную функцию std::sort, так как для этого требуются итераторы с произвольным доступом, которые list итераторами не являются.

4 голосов
/ 09 июля 2009

Вы передаете класс в качестве аргумента функции. Вы не можете сделать это - вы должны создать экземпляр класса и передать это:

substring_list.sort(Substring::OccurrenceComparator());

Обратите внимание на дополнительные скобки после OccurenceComparator выше, которые создают временный объект класса с использованием конструктора по умолчанию.

Другая ошибка заключается в том, что вы вызываете list::sort как статическую функцию в классе std::list. Это не статично, поэтому вам нужно вызывать его как функцию-член в substring_list.

3 голосов
/ 09 июля 2009

Первоначальная проблема уже была решена Павлом Минаевым выше.
Но некоторые дополнительные заметки.

Оператор (), вероятно, должен быть константным (как и параметры).
Для таких простых классов проще просто сделать их структурами.

struct OccurrenceComparator
{
    bool operator() (Substring const* a, Substring const* b)  const;
};

Обратите внимание, что сравнение должно обеспечивать строгий слабый порядок:

template
void sort (BinaryPredicate comp);

Comp должен быть функцией сравнения, которая вызывает строгое слабое упорядочение (как определено в требованиях LessThan Comparable к объектам типа T. Эта функция сортирует список * в соответствии с Comp. Сортировка стабильна, то есть относительная порядок эквивалентных элементов сохраняется. Все итераторы остаются действительными и продолжают указывать на одни и те же элементы. [6] Число сравнений приблизительно равно N log N, где N - размер списка.

...