expected primary expression in algorithm::binary_search call - c++

I hope this is not painfully obvious. I am getting this cryptic error :
fold.cpp:92: error: expected primary-expression before ‘)’ token
The line that it is referring to is:
if (binary_search (corpus.begin(),corpus.end(), left, customArray::operator<(customArray)))
I arrived at this error after using the simpler call:
if (binary_search (corpus.begin(),corpus.end(), left))
and getting this error message (the important part is the note at the end, saying to change it to the above call)
In function ‘bool std::binary_search(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = std::_List_iterator<customArray>, _Tp = std::string [3]]’:
fold.cpp:92: instantiated from here
/usr/include/c++/4.2.1/bits/stl_algo.h:4240: error: no match for ‘operator<’ in ‘__val < __i. std::_List_iterator<_Tp>::operator* [with _Tp = customArray]()’
/usr/include/c++/4.2.1/bits/stl_algo.h: In function ‘_ForwardIterator std::lower_bound(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = std::_List_iterator<customArray>, _Tp = std::string [3]]’:
/usr/include/c++/4.2.1/bits/stl_algo.h:4239: instantiated from ‘bool std::binary_search(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = std::_List_iterator<customArray>, _Tp = std::string [3]]’
fold.cpp:92: instantiated from here
/usr/include/c++/4.2.1/bits/stl_algo.h:2906: error: no match for ‘operator<’ in ‘__middle. std::_List_iterator<_Tp>::operator* [with _Tp = customArray]() < __val’
fold.cpp:16: note: candidates are: bool customArray::operator<(customArray)
Essentially, I am trying to use a binary search on a linked list of custom (array type) objects. The rest of the relavent code is here:
// here is the custom class I am using in the list
class customArray
{
public:
// this is a somewhat lame way to compare, but it seems to work
bool operator< (customArray temp)
{
return array[0] < temp.array[0];
}
bool operator> (customArray temp)
{
return array[0] > temp.array[0];
}
bool operator== (customArray temp)
{
return ((array[0] == temp.array[0]) && (array[1] == temp.array[1]) && (array[2] == temp.array[2]));
}
string array[3];
};
//All of this stuff is in main
customArray one;
//some processing here to fill one
corpus.push_back (one);
// sort the list
corpus.sort();
corpus.unique();
string left [3];
if (binary_search (corpus.begin(),corpus.end(), left, customArray::operator<(customArray)))
{
}
I hope this is easy to understand. Let me know if there is any way that I can clarify.

Your first error message was because binary_search uses < on the iterators, but list's iterators don't support <. This error has nothing to do with whether or not you pass a comparison function as an argument to binary_search.
Your second error message is because you specified the type when passing the function as an argument. That's basically the same as calling a function as f(int x) instead of f(x), which is syntactically incorrect. It should just be customArray::operator<. However, as I said before, that won't help you because you'll just get the first error message again.
Basically you can't perform a binary search on a linked list.

You are putting the whole signature of your functor inside your call to binary_search. You don't need the 'bool' there.

Related

C++ BinarySearchTree Inserting an element

So I'm getting these errors when trying to insert to a binary search tree, I've literally been stuck on this one problem for hours not knowing what to do and I couldn't find anything on the internet to help so thanks in advance.
In file included from Indexer.h:19,
from Indexer.cpp:20:
BinarySearchTree.h: In member function ‘void BinarySearchTree<Comparable>::insert(const Comparable&, BinarySearchTree<Comparable>::BinaryNode*&) [with Comparable = Word]’:
BinarySearchTree.h:108: instantiated from ‘void BinarySearchTree<Comparable>::insert(const Comparable&) [with Comparable = Word]’
Indexer.cpp:109: instantiated from here
BinarySearchTree.h:165: error: passing ‘const Word’ as ‘this’ argument of ‘bool Word::operator<(Word&)’ discards qualifiers
BinarySearchTree.h:167: error: no match for ‘operator<’ in ‘t->BinarySearchTree<Word>::BinaryNode::element < x’
Word.h:33: note: candidates are: bool Word::operator<(Word&)
make: *** [Indexer.o] Error 1
And the Code I think is creating it is from Indexer.cpp line 109
Word takes in two parameters, current being the string and count is equal to 0 for this function.
Indexer.cpp
BinarySearchTree<Word> filterTree;
Line 109: filterTree.insert(Word(current, count));
BinarySearchTree.h
void insert( const Comparable & x )
{
Line:108 insert( x, root );
}
Word.cpp :operator<
bool Word::operator<(Word &RHS)
{
if(m_wordText < RHS.GetWord())
{
return true;
}
else
return false;
}
Member comparators should (almost) always be const functions that take const parameters,
bool Word::operator<(Word const&) const;
Any function called within a const function must also be const itself
std::string Word::GetWord() const;
(As #NeilKirk correctly points out this should probably return std::string const&).
You should learn about const correctness as it can stop you from making silly mistakes in your code.
Also using a non-member comparator is usually preferred as it allows both sides of the expression to use conversion operators
bool operator<(Word const& lhs, Word const& rhs)
{
return lhs.GetWord() < rhs.GetWord();
}

error: request for member ‘speak’ in ‘it.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator*

This is probably a stupid error, but I am getting the following error:
error: request for member ‘speak’ in ‘it.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Bird* const*, _Container = std::vector<Bird*>, __gnu_cxx::__normal_iterator<_Iterator, _Container>::reference = Bird* const&]()’, which is of non-class type ‘Bird* const’
The code that is causing the error is:
void Aviary::speakAll(std::ostream &os) const{
for(std::vector<Bird*>::const_iterator it = birds.begin(); it != birds.end(); it++){
it->speak(os);
}
}
The structure that I am using to store the Bird pointers is:
typedef std::vector<Bird*> Birds;
void Aviary::addBird(Bird *bird){
if(!bird) throw std::logic_error("");
birds.push_back(bird);
}
The question is how do I call an objects member function from a pointer?
You are iterating over pointers, not values. To refer to the value an iterator points to, use -> or *, your value is a pointer, so you need a second dereferentation:
(*it)->speak(os);
// or
(**it).speak(os);
Here, *it means give me the pointer, then the second * or the -> means dereference the pointer.

Sorting objects in C++

I have a really strange error when I try and sort objects using a compare method in C++
required from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Album*, std::vector<Album> >; _Compare = bool (*)(const Album*, const Album*)]'
It doesn't seem to be a standard error, but I can't see anything wrong with my code. Is it a problem with the compare method, or the sort itself. Any help would be greatly appreciated.
I have attached the relevant code:
Album.cpp: http://pastebin.com/0tNrbdrT
Album.h: http://pastebin.com/iY2Yy7qM
AlbumCollection.cpp: http://pastebin.com/gWj0nS8S
AlbumCollection.h: http://pastebin.com/bFrxme5n
AlbumCollection Sort:
void AlbumCollection::sortAlbums(){
std::sort(albums.begin(), albums.end(), compareAlbums);
}
Album compare method:
bool Album::compareAlbums(const Album* a1,const Album* a2)
{
if (a1->getArtist() == a2->getArtist()){
return (a1->getTitle() < a2->getTitle());
}else{
return a1->getArtist() < a2->getArtist()
}
}
The error is: http://pastebin.com/PeXk0FUT
I'm not sure how much is relevant, I'm quite new to C++
There are two errors here. First, the compareAlbums function needs to be a free function, not a member function of the Album class. Second, the compareAlbums function must take const-references to Album objects, since that is what you store in your vector. So, this should fix it:
bool compareAlbums(const Album& a1,const Album& a2)
{
if (a1.getArtist() == a2.getArtist()){
return (a1.getTitle() < a2.getTitle());
} else {
return a1.getArtist() < a2.getArtist()
}
}
You've tried to sort a std::vector using a function that takes pointers as arguments. The comparison function is given references to its arguments, not pointers.
The immediate problem should be fixed simply by taking the comparison function and adjusting it from
bool compare(const Album*, const Album*)
to
bool compare(Album const &, Album const &)

How do I defeat this C++ Vector Sorting error?

Here's the problem code I'm attempting to compile:
bool TeamMatcher::simpleComparator(Student first, Student second){
return (first.numberOfHrsAvailable < second.numberOfHrsAvailable);
}
void TeamMatcher::sortRosters(){
sort(rosterExcellent.begin(), rosterExcellent.end(), simpleComparator);
sort(rosterGood.begin(), rosterGood.end(), simpleComparator);
sort(rosterOK.begin(), rosterOK.end(), simpleComparator);
sort(rosterPoor.begin(), rosterPoor.end(), simpleComparator);
sort(rosterNoSay.begin(), rosterNoSay.end(), simpleComparator);
}
Then here's the error I'm getting:
TeamMatcher.C: In member function ‘void TeamMatcher::sortRosters()’:
TeamMatcher.C:51: error: no matching function for call to ‘sort(__gnu_cxx::__normal_iterator<Student*, std::vector<Student, std::allocator<Student> > >, __gnu_cxx::__normal_iterator<Student*, std::vector<Student, std::allocator<Student> > >, <unresolved overloaded function type>)’
/usr/include/c++/4.2.1/bits/stl_algo.h:2852: note: candidates are: void std::sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Student*, std::vector<Student, std::allocator<Student> > >, _Compare = bool (TeamMatcher::*)(Student, Student)]
It repeats this error for the four remaining sorts. I don't understand, I'm basically copy/pasting this solution from here: http://www.cplusplus.com/reference/algorithm/sort/
Any help would be greatly appreciated!
You need to declare your simpleComparator as a static method, otherwise it won't fit the type expected by std::sort.
To be perfectly correct, you should also then pass it as TeamMatcher::simpleComparator, see here for details.
Try this instead for your comparison function:
bool simpleComparator(const Student& first, const Student& second){
return (first.numberOfHrsAvailable < second.numberOfHrsAvailable);
}
Note that the comparison function is not a member of your TeamMember class, and passing const references in prevents needless copying.
You can take one step further and define a comparison method for Students
bool Student::operator<(const Student& first, const Student& second)
{
return (first.numberOfHrsAvailable < second.numberOfHrsAvailable);
}
Now you can just call sort on your students and it'll have a comparison method to use:
std::sort(studentIter.begin(), studentIter.end());
However in this case I recommend the first approach, unless you always want to compare Students by the number of hours available. For instance, this may be confusing to another programmer:
if ( studentA < studentB )
{
// Do stuff
}
It may be confusing because it's not readily apparent how you would compare two students (GPA, attendances, hours available, height, IQ, whatever...)

No matching function for call

I've been getting this error, and I can't figure out how to fix it:
btree.tem:98: instantiated from 'std::pair<typename btree<T>::iterator, bool> btree<T>::insert(const T&) [with T = char]'
test.cpp:13: instantiated from here
btree.tem:37: error: no matching function for call to 'btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)'
btree.h:178: note: candidates are: void btree<T>::addElem(std::_List_iterator<node<T>*>&, node<T>&) [with T = char]
btree.tem:98: instantiated from 'std::pair<typename btree<T>::iterator, bool> btree<T>::insert(const T&) [with T = char]'
test.cpp:13: instantiated from here
btree.tem:48: error: no matching function for call to 'btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)'
Inside my header file I have this setter function:
void addElem (std::_List_iterator<node<T>*>& itr, node <T>& n) {
neighbours.insert(itr, n);
}
and I don't know what's wrong with it. The error seems to happen whenever I call it like this:
class list < node<T>* >::iterator itr = bt->level().begin();
node <T>*n = new node<T>(elem, bt->max());
bt->addElem(itr, n);
What is the problem?
The compiler is looking for:
btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)
But it only found something for:
btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>&)
You're passing a pointer to your function. You've not defined an addElem that takes a pointer as its last argument.
The error is not "instatiated from..." - that's the context describing which template instantiations lead to the error.
The error is
btree.tem:37: error: no matching function for call to
'btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)'
And a candidate is listed:
note: candidates are:
void btree<T>::addElem(std::_List_iterator<node<T>*>&, node<T>&)
[with T = char]
So it is expecting a node<char>, not a pointer node<char>*.
n is a pointer, so you have to write this:
bt->addElem(itr, *n);
It is clear from the error message:
btree.tem:37: error: no matching function for call to
'btree<char>::addElem(std::_List_iterator<node<char>*>&, node<char>*&)'
btree.h:178: note: candidates are:
void btree<T>::addElem(std::_List_iterator<node<T>*>&, node<T>&) [with T = char]
See the second parameter type in the error, as well as in the suggested candidates.