C++ BinarySearchTree Inserting an element - c++

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

Related

c++ overloading function including bool and integer arguments

a simple and I guess easy to answer question (if I did not already got it myself). The following overloaded functions:
void BR(const bool set) { backwardReaction_[nReac_] = set; }
bool BR(const int reactionNumber) const { return backwardReaction_[reactionNumber]; }
The first function is a setter and the second a getter function. backwardReaction_ is of type std::vector<bool>. The problem occurs whenever I want to call the second function. Here I get a compiler error overload function BR(xy) ambigious.
int main()
.
.
const int i = 3;
bool a = chem.BR(i);
The compiler error is equal to:
chemistryTestProg.cpp: In function ‘int main()’:
chemistryTestProg.cpp:74:34: error: call of overloaded ‘BR(const int&)’ is ambiguous
const bool a = chem.BR(i);
^
In file included from ../../src/gcc/lnInclude/chemistryCalc.hpp:38:0,
from ../../src/gcc/lnInclude/chemistry.hpp:38,
from chemistryTestProg.cpp:35:
../../src/gcc/lnInclude/chemistryData.hpp:266:18: note: candidate: void AFC::ChemistryData::BR(bool)
void BR(const bool);
^~
../../src/gcc/lnInclude/chemistryData.hpp:322:22: note: candidate: bool AFC::ChemistryData::BR(int) const
bool BR(const int) const;
^~
I guess that I get the problem because of the types bool and int which are identically (true => int(1), false => int(0). As I am changing the getter name to, e.g., bool getBR(const int reactionNumber) {...} everything works fine. So I guess the problem is about the similarities of the bool and int treatment within c++. I also tried a variety of different calls such as:
const bool a = chem.BR(4)
const bool a = chem.BR(int(5))
const bool a = chem.BR(static_cast<const int>(2))
bool a = chem.BR(...)
Thus, I think it is really related to the bool andint overloading arguments. Nevertheless, I made a quick search and did not find too much about these two overload types and resulting problems. Tobi
This is because you declared BR(int), but not BR(bool), to be const. Then when you call BR(int) on a non-const object, the compiler has two conflicting matching rules: parameter matching favours BR(int), but const-ness matching favours BR(bool).

Invalid initialization of type when using sort

I have the following code to sort a vector of a custom type. It used to work, but after building the code on another system it gives an error at compile time.
The context the sort() call is made.
std::vector<std::vector<AssemblyObject>>* LegoAssembler::getLayers(std::vector<AssemblyObject> completeAssembly)
{
std::vector<std::vector<AssemblyObject>>* layers = new std::vector<std::vector<AssemblyObject>>();
std::vector<AssemblyObject> cLayer;
double lastZ = 0;
std::sort(completeAssembly.begin(), completeAssembly.end(), AssemblyObject::compare);
...
}
The sorting function
bool AssemblyObject::compare(AssemblyObject &a, AssemblyObject &b){
return (a.getPosition()[2] < b.getPosition()[2]) ||
((a.getPosition()[2] == b.getPosition()[2]) && (a.getPosition()[1] > b.getPosition()[1])) ||
((a.getPosition()[2] == b.getPosition()[2]) && (a.getPosition()[1] == b.getPosition()[1]) && (a.getPosition()[0] > b.getPosition()[0]));
}
The Error
/usr/include/c++/4.8/bits/stl_algo.h:2263: error: invalid initialization of reference of type ‘AssemblyObject&’ from expression of type ‘const AssemblyObject’
while (__comp(*__first, __pivot))
/usr/include/c++/4.8/bits/stl_algo.h:2263: error: invalid initialization of reference of type ‘AssemblyObject&’ from expression of type ‘const AssemblyObject’
while (__comp(*__first, __pivot))
^
^
As I said, this happened after building the code on another system. I was thinking it had something to do with changing compiler versions, but then again, I think something as simple as a sort function wouldn't break. Plus I'd like the code to compile on both compilers if that was the case.
Really would appreciate some help,
Your code is attempting to take a non-const reference to a const object, which is not permitted. The compare function doesnt modify its arguments so change:
bool AssemblyObject::compare(AssemblyObject &a, AssemblyObject &b){
To
bool AssemblyObject::compare(const AssemblyObject &a, const AssemblyObject &b){
The error is pretty clear - you need compare to accept const lvalue-references, not mutable ones:
bool AssemblyObject::compare(const AssemblyObject &a, const AssemblyObject &b)
{
/* as before */
}

When to pass by reference for overloading operators in c++?

I have implemented a custom pointer class, lets call it japan. Here is a declaration and definition, as well as a main function I am trying to work with.
class japan
{
public:
japan(T *ptr) : ptr(ptr)
{}
T *get()
{
return this->ptr;
}
bool operator==(const T *&other)
{
return ( this->get() == other );
}
friend bool operator==(const T *&l, japan<T> r)
{
return ( r == l );
}
private:
T *ptr;
};
int main(void)
{
int j;
int *k = & j;
japan<int> nihon(k);
if(k == nihon)
if(nihon == k)
std::cout << "yay\n";
if(nihon == NULL)
return 1;
else
return 0;
if(NULL == nihon)
return 5;
}
My == operator seem to working fine on actual T *s when they are passed in, however if I evoke it with NULL my compiler produces the errors:
stuff.cpp:40:15: error: no match for 'operator==' in '0l == nihon'
stuff.cpp:40:15: note: candidate is:
stuff.cpp:21:16: note: bool operator==(const int*&, japan<int>)
stuff.cpp:21:16: note: no known conversion for argument 1 from 'long int' to 'const int*&'
From what I understand... there should be some form of conversion from T * to long int, or NULL's assignment operator would not function. I then reworked my operator a little.
Both of these functions work
friend bool operator==(T *l, japan<T> r);
friend bool operator==(const T *l, japan<T> r);
However This one fails.
friend bool operator==(const T *&l, japan<T> r);
This makes scene to me, changing NULL would change a value that is never used, but it is a const reference... so why does this fail. Is it common in c++ to not use references on boolean operators? Most of the examples I see always use a reference, but this seems like this would only work for lvalues... So is it better practice to pass by value while overloading?
ALSO:
Why would I get the warning :
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
ptr.h:106:9: note: candidate 1: bool japan<T>::operator==(const T* const&) const [with T = Geometry]
stuff.cpp:239:15: note: candidate 2: operator==(int, long int) <built-in>
Is my japan class somehow exposing its self as a T when == is used, I ask this because I found this class in something I was working on with no == operator defined (despite it being used in many places), and I added one... only to find no end of problems.
In C++, 0 is an abused integer. It is used to reflect, well, 0 as a value of type int and it is also used to represent a null pointer.
Your types are fundamentally different. There's no const correctness issue, it's just that NULL, is a macro for 0 and that's something that doesn't cooperate well with generic programming. You could try
static_cast<T*>(NULL);
when comparing with null pointer, or better yet use nullptr, which is what the new standard wants you to be using when you mean "a null 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 &)

Compilation error on operator overloading when sorting vector

I have a class roughly defined like below. Among others, it has a < comparison operator.
class DictionarySearchItem {
public:
DictionarySearchItem();
double relevance() const;
bool operator<(const DictionarySearchItem& item) { return relevance() > item.relevance(); }
};
typedef std::vector<DictionarySearchItem> DictionarySearchItemVector;
I then use the class this way:
DictionarySearchItemVector searchItems;
for (unsigned i = 0; i < entries.size(); i++) {
// ...
// ...
DictionarySearchItem item;
searchItems.push_back(item);
}
However when I try to sort the vector:
std::sort(searchItems.begin(), searchItems.end());
I'm getting the following compilation error with MinGW.
/usr/include/c++/4.2.1/bits/stl_algo.h:91: erreur : passing 'const hanzi::DictionarySearchItem' as 'this' argument of 'bool hanzi::DictionarySearchItem::operator<(const hanzi::DictionarySearchItem&)' discards qualifiers
I don't quite understand what is incorrect with my code and the error message is not clear to me. The same code compiles fine with MSVC2008. Any idea what could be the issue?
You need to make the less-than operator const:
bool operator<(const DictionarySearchItem& item) const { ... }
^
The reason is probably that sort relies on the fact that elements being compared cannot change as a result of the comparison. This can be enforced by having both sides of the < comparison be const, which means the operator has to be const, as well as it's argument.