Overloading the == function - c++

I am currently working on creating an overloaded function for the == operator. I am creating an hpp file for my linked list and I can't seem to get this operator working in the hpp file.
I currently have this:
template <typename T_>
class sq_list
{
bool operator == ( sq_list & lhs, sq_list & rhs)
{
return *lhs == *rhs;
};
reference operator * () {
return _c;
};
};
}
I get about 10 errors but they pretty much repeat as errors:
C2804: binary 'operator ==' has too many parameters
C2333:'sq_list::operator ==' : error in function declaration; skipping function body
C2143: syntax error : missing ';' before '*'
C4430: missing type specifier - int assumed. Note: C++ does not support default-int
I've tried changing things around but I constanly get the same errors as above
Any tips or assistance on this is greatly appreciated.

The member operator only has one argument, which is the other object. The first object is the instance itself:
template <typename T_>
class sq_list
{
bool operator == (sq_list & rhs) const // don't forget "const"!!
{
return *this == *rhs; // doesn't actually work!
}
};
This definition doesn't actually make sense, since it just calls itself recursively. Instead, it should be calling some member operation, like return this->impl == rhs.impl;.

You are declaring the == overload as part of the class definition, as a method instances will get. Thus, the first parameter you request, lhs, is already implicit: remember, within an instance's methods you have access to this.
class myClass {
bool operator== (myClass& other) {
// Returns whether this equals other
}
}
The operator==() method as part of a class should be understood as "this object knows how to compare itself to others".
You can overload operator==() outside the class to receive two arguments, both objects being compared, if that makes more sense to you. See here:
http://www.learncpp.com/cpp-tutorial/94-overloading-the-comparison-operators/

http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html
The comparison operators are very simple. Define == first, using a function signature like this:
bool MyClass::operator==(const MyClass &other) const {
... // Compare the values, and return a bool result.
}
HOW to compare MyClass objects is all your own.

Related

Comparing two objects of the same class

I am trying to overload the == operator in C++.
#include <string>
using namespace std;
namespace date_independent
{
class clock
{
public:
int clockPair[2] = {0,0};
operator string() const
{
string hourString;
string minString;
if(clockPair[0]<10)
{
hourString = "0"+to_string(clockPair[0]);
}
else
{
hourString = to_string(clockPair[0]);
}
if(clockPair[1]<10)
{
minString = "0"+to_string(clockPair[1]);
}
else
{
minString = to_string(clockPair[1]);
}
return hourString+":"+minString;
};
bool operator ==(const clock&clockOne, const clock&clockTwo) const
{
return string(clockOne)==string(clockTwo);
};
};
};
There is much more code than I have included, but this is the important part. I want it so that the == operator can compare two objects of class clock. E.g., object1==object2. Is there anybody that can help me?
A binary operator like == can be overloaded either as a member function with a single parameter (this being the left-hand operand, and the parameter being the right-hand one), or as a non-member function with two parameters for the two operands.
So either
move your operator declaration outside the class declaration (moving the definition to a source file, or declaring it inline if you keep the definition in the header); or
add friend to the definition, so that it declares a non-member in the surrounding namespace; or
remove the first argument from the member function, using this instead.
As a member, it would look like
bool operator==(const const & clockTwo) const {
return string(*this) == string(clockTwo);
}
You might also want to compare the two integer values directly to save the expense of making strings. You should also remove the rogue ; after the function and namespace definitions, although most modern compilers shouldn't object to their presence.
Your comparison function has been written to take two clock objects and compare them, so it should be a non-member function (after the class definition), without the const qualifier.
bool operator==(const clock& clockOne, const clock& clockTwo)
{
return string(clockOne) == string(clockTwo);
}
When you have an operator inside the class definition, the left-hand argument is implicitly provided for you (it's *this), so if you wanted to implement it there you'd need something like:
bool operator==(const clock& clockTwo) const
{
return string(*this) == string(clockTwo);
}
Still, that's not recommended for == as if you have say an implicit constructor from another type T, you won't be able to write code ala my_t == my_clock with the member version unless T provides a suitable comparison operator (for clock or string). A non-member operator gives more symmetric operation.
Overloading can be done inside or outside the class definition. If you want to do it inside, the function receives only one argument. You should compare this with that argument.
bool operator ==(const clock&clockTwo) const
{
return string(*this)==string(clockTwo);
}
Note the const after the argument, it means that you won't change this inside the function.
On the other hand, if you want to do it outside the class definition, it needs two arguments, and you should compare them.
bool operator ==(const clock&clockOne, const clock&clockTwo)
{
return string(clockOne)==string(clockTwo);
}
Also note that it'll be faster to compare the clockPair of the objects rather than making the string and comparing them.
Though your question is poorly worded I believe that you are asking why the operator you've defined is not working?
If you are defining the operator as a member of the class it only takes one parameter. For example:
class clock {
bool operator ==(const clock& rhsClock) const
{
// Note: this is the lhsClock
return string(*this) == string(otherClock);
}
};
When you define the operator as a free function (not as a part of the class) then you need to define both parameters:
class clock {
// ... class declaration ...
};
bool operator ==(const clock& lhsClock, const clock& rhsClock)
{
return string(lhsClock) == string(rhsClock)
}
Where the comparison would look like this:
if (lhsClock == rhsClock) // ... do something ...

Comparison function for C++ STL set: Can comparison function be a member function of a class?

I have to use STL set and I want to define my own comparison function. But as per my requirement this comparison function shouldn't be a global, rather should be a public member of a class.
//CLASS DEFINITION
class IDENTIFERS
{
public:
IDENTIFIERS();
~IDENTIFIERS();
bool compare_identifier(int Identifier, int Identifier);
public:
std::set <Identifier, bool(*)(Identifier, Identifier)> set_instance;
};
//CLASS Constructor
IDENTIFIERS::IDENTIFIERS()
{
std::set <Identifier, bool(*)(Identifier, Identifier)> set_instance(compare_identifier);
}
If I write a piece a code as mentioned above. It doesn't compile as comparison function's prototype doesn't match with compare_identifier() function.
Is there a way to do it?
A non-static member function takes an implicit first parameter for this, so your compare_identifier actually has three parameters. If you need it to be a non-static member function, you need to bind the member function's implicit first parameter to an instance of IDENTIFIERS, for example,
#include <set>
#include <functional>
struct Identifier { int id; };
class IDENTIFERS
{
public:
IDENTIFERS() : set_instance(std::bind(&IDENTIFERS::compare_identifier,
this,
std::placeholders::_1,
std::placeholders::_2))
{}
bool compare_identifier(const Identifier& lhs, const Identifier& rhs)
{
return lhs.id < rhs.id;
}
public:
std::set <Identifier, std::function<bool(const Identifier&, const Identifier&)>> set_instance;
};
There are a number of errors in your sample code.
The zero-th error is somewhat style-related: classes should be named all-lowercase-with-underscores or CamelCase.
The first error:
bool compare_identifier(int Identifier, int Identifier);
you can't have the same identifier for both function parameters (also, style-related, function parameters should be all-lowercase or camelCased), like
bool compare_identifier(int id1, int id2);
The second error is that this:
std::set <Identifier, bool(*)(Identifier, Identifier)> set_instance;
assumes that you have a class Identifier somewhere. Which something tells me you don't, since your class is called IDENTIFIERS. If you do have an Identifier class, I should assume that your compare_identifier function is like:
bool compare_identifier(const Identifier& id1, const Identifier& id2);
and that your set_instance declaration is like:
std::set<Identifier, bool(*)(const Identifier&, const Identifier&)> set_instance;
The third error is that your constructor does not do what you are assuming it does (constructing the set_instance member), but it would be (if syntatically valid) constructing a local variable called set_instance. So, your constructor should go something like:
IdentifierBucket::IdentifierBucket() :
set_instance(std::bind(compare_identifier, this, _1, _2)) {
}
But all this is moot... because the comparator for set also does not do what you think it does (see if two items are equal or not) but it gives them order (the default comparator is std::less...
What you really want is something like:
#include <set>
#include <functional>
struct Identifier {};
struct IdentifierComparator {
IdentifierComparator() {};
bool operator()(Identifier id1, Identifier id2); // WRITE THIS
};
class IdentifierBucket {
public:
IdentifierBucket() {};
~IdentifierBucket() {};
private:
std::set <Identifier, IdentifierComparator> set_instance;
};
Making compare_identifier() static is the easiest way to solve this. Here is how you can fix your code so that it compiles, assuming Identifier is defined elsewhere:
// Watch for the typo (missing 'I') in your code above
class IDENTIFIERS // Note, all-uppercase names are usually reserved for macros
{
public:
IDENTIFIERS();
// N.B: This function needs to take two `Identifier`s as its arguments
// (not two `int`s)
static bool compare_identifier(Identifier const &l, Identifier const& r)
{
return l.custom_less_than(r);
}
// typedefs can make your code more readable, especially with function pointers.
typedef bool (*identifier_comparator)(Identifier const &l, Identifier const& r);
typedef std::set<Identifier, identifier_comparator> identifier_set;
identifier_set set_instance;
};
IDENTIFIERS::IDENTIFIERS()
:set_instance(compare_identifier) // Initialise here
{
// Don't shadow `set_instance` in the body of the constructor!
}
Following comment
Making compare_identifier() static (in IDENTIFIERS) will not affect the accessibility of members of the Identifier class. The logic to compare two Identifier objects should reside either within Identifier, like this:
class Identifier
{
public:
// If you define this, then you won't need to specify a custom comparator
bool operator <(Identifier const& r) const
{
// return true if `*this` is logically less-than `r`; false otherwise.
}
bool custom_less_than(Identifier const& r) const
{
// Some other way of comparing objects. Perhaps reverse-alphabetically
// or similar.
// return true if `*this` is logically less-than `r`; false otherwise.
}
};
...or within free functions but these won't have access to the private members.

Compilation error about operator reloading using boost::variant

I'am trying to learn boost.variant. However, the code which I copied from a book won't pass the compilation:
class var_print : public boost::static_visitor<void>
{
public:
template<typename T>
void operator()(T &i) {
i *= 2;
cout<<i<<endl;
}
};
Here is how I tried to use it.
typedef boost::variant<int,double,string> var_t;
var_t v(1); //v->int
boost::apply_visitor(var_print(),v);
The compiler generates the following error:
ERROR:no match for 'operator*=' in 'i *= 2'
That puzzles me,since template function will determine the type of parameter whenever it's called and int should defined the operator *=.
You need to have a separate operator() for std::string& since no operator *= is defined for std::string.
In addition, your operator must be marked const since you are passing a temporar visitor instance to apply_visitor.

Is there an equivalent of the Java equals method in c++?

Is there something like Java equals()? To compare if object is the same type ?
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof ViewMode)) {
return false;
}
ViewMode dm = (ViewMode) obj;
return dm.width == w
&& dm.h == h
&& dm.b == b
&& dm.f == f;
}
public int hashCode() {
return w ^ h ^ f ^ b ;
}
For the idiomatic equivalent of your example, you would define operator== as follows:
friend bool operator==(const ViewMode &lhs, const ViewMode &rhs) {
return (lhs.w == rhs.w) && the rest;
}
friend bool operator!=(const ViewMode &lhs, const ViewMode &rhs) {
return !(lhs == rhs);
}
In C++ you don't normally write a function to allow ViewMode objects to be compared with something that has nothing at all to do with ViewMode. I suppose that if you really wanted that comparison to return false, rather than refusing to compile, then you could add a couple of template operators (as free functions, outside the class):
template <typename T>
bool operator==(const ViewMode &, const T&) {
return false;
}
template <typename T>
bool operator==(const T &, const ViewMode&) {
return false;
}
but I really don't recommend it. That Java idiom doesn't apply to C++, because in C++ you pretty much should never have an object, but have no idea of its type.
If you want your equals function to be virtual, then it's probably best to write an equals() virtual function, rather than using operator== for it. You'd write it to take a const ViewObject & as parameter, so no need for any equivalent to the instanceof check. Which is just as well, because C++ does not have any way to take an object of totally unknown type and test whether it is an instance of a specified type.
You rarely need a polymorphic equals function in C++, but if you were using it for example in std::unordered_map, then you'd specify the extra template parameters to the unordered_map. Give it an equality comparison function that takes two pointers and calls equals on one or the other, and a hash function that does something sensible.
No. C++ does not have a global type model like Java. There is no Object type from which all other types inherit, so there are no methods (like equals) that are defined for all classes.
C++ provides a framework for building a type model with a universal comparison operation: operator ==. It is up to you to build out all of the implementations of this in all of your classes so that they interact correctly. But there is no default implementation comparable to Object.equals.
You can define the operator== in your class.
You might be able to use the typeid operator for this.

template class and overloading '=='

I'm making some stack, in which I need to uses this kind of comparison in some function. But I got stuck since I don't know how the prototype for this should look like.
I have the following line in a function.
template <class T>
void function1(T i)
{
if(i == 'a')
//do something
}
I wonder know how the overload prototype should look like for it?
EDIT
Dunno if it's worth to mention, anyway this is what I have tried so far
template
bool Stack<T>::operator==(char c) const
{
cout << c << endl; // just some test
}
No need to comment how this function works, as I have not finished it yet. This part will compile, however at the part where I call this function for the first time is in the Stack::push(T i). The compiler will complain that there are no matching function for this.
error: no match for 'operator==' in 'i == '#''
For overloading operators, the name of the function is operator followed by the actual operator, so operator==. It returns bool. I don't know what your arguments should be based on your code. Probably Stack<T>&, and you need two of them to compare if it's a free function, and one to compare to this if it's a member function.
If you have ways to convert to a Stack<T>, then prefer a free function so that you can convert the left-hand-side.
I'm not sure I understand your question. In order for an instantiation of template function function1 to be well-formed, you'll have to provide a operator== which compares a T and (I'll suppose) a char.
Now, you have two options here :
Provide a bool operator==(char) const member function in your type, for example :
struct A {
bool operator==(char) const { /* ... */ }
};
function1(A()); // OK : comparison uses A::operator==(char)
Provide bool operator==(const T &, char) as a free function, for example :
struct A { /* ... */ };
bool operator==(const A &, char) { /* ... */ }
function1(A()); // OK : comparison uses operator==(const A &, char)
So every T in your function1(t) has to implement operator ==;
For example, as a member function
class A
{
public:
bool operator == (char) const;
};
or a non-member operator:
class A
{
public:
friend bool operator == (const A&, char);
};