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"
Related
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).
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 */
}
The error happen when I try to use one of my get function on parameter inside member functions. The error is:
Invalid arguments '. Candidates are : int getTotalArea() .
here is an example from my code :
class Apartment{
public : // ...
enum SquareType {EMPTY, WALL, NUM_SQUARE_TYPES};
bool operator<(const Apartment& apartment); // done - need help
int getTotalArea(); // done
private:
int price;
int length;
int width;
SquareType** squares;
};
int Apartment::getTotalArea()
{
int count=0;
for(int i=0;i<width;i++)
{
for(int j=0;j<length;j++)
{
if(squares[i][j]==EMPTY)
{
count++;
}
}
}
return count;
}
bool Apartment::operator<(const Apartment& apartment)
{
int thisArea=this->getTotalArea();
int paramArea=apartment.getTotalArea(); // the error line is here !!!
//the error is Invalid arguments '. Candidates are : int getTotalArea() .
double thisRatio=((double)price)/thisArea;
double paramRatio=((double)apartment.price)/paramArea;
if(thisRatio==paramRatio)
{
return price < apartment.price;
}
return thisRatio<paramRatio;
}
Have I done something wrong ?
It's the first time I'm using c++ ... by the way - any comments for the rest of the code are fine as well.
From the answer of PcAF seems you've heavily changed your initial post without modifying your question. Very bad!
However, the problem you're facing now with getTotalArea is that it isn't declared const.
See https://stackoverflow.com/a/751690/781933 for explanation.
Seems like you misunderstood operator overloading (as members)
When overloading some operator as member, then first operand of that operator is object on which member operator overload is called and second operand is parameter to that function (in case of binary operators).
operator + can be used as binary(2 operands) or unary operator(1 operand).
Here it seems like you want to overload binary version as member:
Apartment operator+(const Apartment& apartment1,const Apartment& apartment2);
but since first operand is object on which that member "function" is called it must take only 1 parameter (which is second operand).
Apartment operator+(const Apartment& apartment2);
Here is the second mistake:
Apartment& operator=(SquareType** squares, int length, int width, int price);
operator = is binary operator (2 operands), therefore if you want to overload it as member function it has to take exactly one parameter (which is second operand of =), not 4 parameters.
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();
}
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.