Error in std :: list :: sort with custom comparator (expected primary expression before ')' token)

The name is the main question. Exact scenario (I use namespace std; '):

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

This is the definition of a comparator:

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

Comparator implementation is intuitive and trivial. I also use a very similar comparator in std :: set, and it works great. When I add the sortByOccurrence () function, it gives me an error in the name.

What should I do?

EDIT: Now I try to pass Substring :: OccurrenceComparator () as a comparator and get the following error:

 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 

Now my line of code:

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

I cannot delete the template, or it gives me an error saying that the template parameters were incorrect.

+1
source share
3 answers

list member sort is a non-static function, so you need to call it on the list instance.

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

Edit: You cannot use the free function std::sort , since it requires random access iterators, for which there is none.

+4
source

You pass the class as an argument to the function. You cannot do this - you need to instantiate the class and pass this:

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

Note the extra brackets after OccurenceComparator above that create a temporary class object using the default constructor.

Another mistake is that you call list::sort as a static function in the std::list class. This is not static, so you need to call it as a member function on substring_list .

+4
source

The original problem has already been solved by Pavel Minaev above.
But some additional notes.

The operator () should probably be const (as well as parameters).
For simple classes like this, it's easier to just create their structures.

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

Please note that the comparison should provide a strict weak order:

template <class BinaryPredicate>

void sort (BinaryPredicate comp);

Comp should be a comparison function that induces a strict weak order (as defined in LessThan Comparable requirements for objects of type T. This function sorts the * this list according to Comp. The sort is stable, that is, the relative order of equivalent elements is preserved. All iterators remain in force and continue to point to the same elements. [6] The number of comparisons is approximately N log N, where N is the size of the list.

+3
source

Source: https://habr.com/ru/post/1384538/


All Articles