In my program, I use many arma::uvecs, and check equality between them like this
#include <armadillo>
using Vec = typename arma::uvec;
Vec v1({0, 0});
Vec v2({0, 1});
bool are_equal = arma::all(v1 == v2);
as I couldn't find any better equality operator in the Armadillo docs. Now that works perfectly fine, but to save some space, and as an exercise in subclassing and operator overloading, I want to define the equality sign directly between the vectors like this:
class Vec : public arma::uvec {
friend bool operator==(const Collapsed& lhs, const Collapsed& rhs) {
return arma::all(lhs == rhs);
}
};
But sadly, I can't get it to work like that. I'm grateful about any hints!
Operator overloads do not need to be part of a class. I would suggest implementing your comparison operator as a free function like this:
bool operator==(const arma::uvec& lhs, const arma::uvec& rhs) {
return arma::all(lhs == rhs);
}
Regarding the friend in your question: As a quick summary, it provides the function that is befriended access to private and protected members of the class where the friend declaration is located. It it is not used to implement functions.
You can read more about it on cppreference or on this SO question
EDIT
Since the above only works if operator== is not already defined, here is a version that overrides it's implementation for a custom subclass:
class Vec : public arma::uvec
{
public:
bool operator==(const Vec& other)
{
// depending on wether arma implemets operator== as member or free function
// return arma::all(this->arma::uvec::operator==(other));
return arma::all(arma::operator==(*this, other));
}
};
Problem is library itself:
Armadillo: C++ library for linear algebra & scientific computing
operators: + − * % / == != <= >= < > && ||
Overloaded operators for Mat, Col, Row and Cube classes
Operations:
+ addition of two objects
− subtraction of one object from another or negation of an object
* matrix multiplication of two objects; not applicable to the Cube class unless multiplying by a scalar
% element-wise multiplication of two objects (Schur product)
/ element-wise division of an object by another object or a scalar
== element-wise equality evaluation of two objects; generates a matrix/cube of type umat/ucube
!= element-wise non-equality evaluation of two objects; generates a matrix/cube of type umat/ucube
and uvec is:
uvec = ucolvec = Col<uword>
so operator== is already there and its functionality is strange/unexpected.
My recommendation is: do not fight with a library. Do not try provide own operator. Just provide a named function areEqual.
Defining a class just to provide own equal operator is not a best choice and if doing that then IMO it is better to use composition not inheritance (depending on requirement it will be more boiler plate code in class itself, but it will be easier to avoid unexpected behaviors).
Related
In making a class, the compare method and the operator== overload should have identical functionality. Therefore, only one implementation is needed, and I'm trying to figure out if there's any reason why it should be defined in the compare method rather than the operator== overload.
Here's the structure defining comparison in compare:
class T {
// definition of field f
...
bool compare(const T& t) const {
if (this->f == t.f) { return true; }
return false;
}
friend bool operator == (const T& lhs, const T& rhs) { return lhs.compare(rhs); }
}
versus in the operator == overloading:
class T {
// definition of field f
...
bool compare(const T& t) const { return *this == t; }
friend bool operator == (const T& lhs, const T& rhs) {
if (lhs.f == t.f) { return true; }
return false;
}
}
TL;DR use second variant with 'virtual' keyword, but it will be better to get rid of this bullshit at all and use operator== only
You should use method compare() only if you have other variant of objects comparison, otherwise it does not make any sense. The reason for this is implementation of std::map, std::set, sorting alghoritms, etc., which use operator==, so if you use first variation of == implementation it will be, basicaly, your operator==, but with other name, which does not make any sense.
If you still want to do it,
-You can use first variant(where == uses compare), but make compare method virtual. In this case you will be able to overload comparison method just like in Java and it will affect on comparison, but still you can do it just by creating operator== for children class, so it still doesn't make any sense
...or you can use second one, but still using 'virtual' keyword to change implementation of parent class in children classes and if you don't like == implementation you can use compare method
Not very relatable example, but I think it might help you. In OpenCV library assignment operator= for class Mat(this class contains literally array of pixels and nothing more) don't actually copies array, but copies only a pointer on array of pixels(because it's heavy operation and it doesn't required in many cases), and for actual copying method clone() used. I think you can use the same solution for your code
I want to implement a representation of matrices. for that I have two types of matrices - regular and sparse, which differ in their implementation - one holds a vector, and the second a map of indices and value, both inherit from Matrix class.
For that, I'm using the strategy pattern, where I create the base abstract class Matrix, two classes that inherit from Matrix - RegMatrix and SparseMatrix, and MyMatrix that holds a pointer to a Matrix.
I want to implement the + operator, which operates on Matrix and receives another Matrix. but when I implement the + operator, I might receive as parameter sparse/regular matrix.
so I have 2 questions:
The only hint I have is to create an iterator of type "matrix", and implement the iterator for each type of matrix (regular and sparse).
how can I do such a thing?
Let's say I implemented an iterator for both types of "matrix". how can I use the different iterators, in case I have to add two different types of matrices? do I have to implement all 4 different cases?
The operator+ looks like:
Matrix& operator+(const Matrix& other)
{
.....
}
Prefer not to implement the functionality in the base class.
Implement the functionality in each of the child classes. This will allow for use of optimal algorithms.
Or you could declare getters and setters as abstract in the Base class and use them in your base class implementation:
struct Matrix_Base
{
virtual int get_value(unsigned int row, unsigned int column) = 0;
virtual void set_value(int value, unsigned int row, unsigned int column) = 0;
Matrix_Base operator+(const Matrix_Base& other)
{
// perform addition
int sum = get_value(row, column) + other.get_value(column, row);
set_value(sum, row, column);
//...
}
};
Remember, when passing a Matrix, the receiving function can only use common functions (interface) of the Matrix. For specifics, functions will have to use specialized (descendants) in the parameter lists.
You may implement + operator only for RegMatrix and 2 conversion operators:
1. From RegMatrix to SparseMatrix
2. From SparseMatrix to RegMatrix
What are performance requirements?
I don't dabble in C++ very often, but I'm learning about data structures and the book uses c++ as it language. I'm currently going over setting up classes.
My issues are:
Visual Studio 2012 is barking about unidentified variables. I have the variables declared in my header, so I'm not quite sure why I'm having the issue.
I'm trying to overload the addition and multiplication operators (as non-member functions) but it is still trying to use it as if I'm only allowed to have one parameter for the overload.
Here is some code for what I'm doing:
1. Unidentified variables
/* Quadratic.h */
#include <iostream>
using namespace std;
class Quadratic
{
public:
// constructors
Quadratic::Quadratic()
// accessors
Quadratic::getA();
Quadratic::getB();
Quadratic::getC();
// mutators
Quadratic::setCoefficients(float coA, float coB, float coC);
private:
float a, b, c, x;
};
Quadratic.cpp:
/* Quadratic.cpp */
#include <iostream>
#include "Quadratic.h"
using namespace std;
class Quadratic
{
// Default constructor
Quadratic::Quadratic()
{
a = 0; // Visual Studio is complaining about a, b, & c
b = 0;
c = 0;
}
/* Mutators */
void Quadratic::setCoefficients(float coA, float coB, float coC)
{
a = coA;
b = coB;
c = coC;
}
/* Accessors */
float Quadratic::getA() const {
return a;
}
float Quadratic::getB() const {
return b;
}
float Quadratic::getC() const {
return c;
}
};
So that is what the first issue is about. I'm not quite sure why it isn't able to find those variables. Can someone point out what I'm doing wrong?
2. Overloading Operator (mismatch on the parameters)
/* Quadratic.h */
/* Overloading Operators */
Quadratic & operator+(const Quadratic & q1, const Quadratic & q2);
Quadratic & operator*(double r, const Quadratic & q);
It is simply telling me that I have too many parameters. I'm thinking it is expecting to do something like q1.operater+(q2) where as I'm wanting to be able to do something like q3 = q1 + q2
Any pointers would be great for fixing these small issues.
Edit
Compiler errors as requested:
error C2804: binary 'operator +' has too many parameters
error C2804: binary 'operator *' has too many parameters
Basically what I mentioned above, perhaps I wasn't clear about it though.
Edit 2
Not sure why it was downvoted, but if you're going to downvote it, at least state why... If it was because the question was novice? Because the question was poorly worded or explained, or just because your ego is too high? No need to put someone down when they are attempting to learn something new.
Other than that, thank you legend2k, john, steve, salda and basile for all taking the time to help me out. I really do appreciate it. C++ is a lot more hands on than Java.
In your Quadratic.cpp you need to remove the line:
class Quadratic
{
As this is hiding your definition of Quadratic in the header file. However, this is hiding errors in your header file. In the .h file you must specify the return types of the methods and you do not need to qualify the method names with Quadratic. To fix the operator overloading error make sure that they are declared outside of the class declaration in your header file.
class Quadratic {
//...
// accessors
float getA() const;
float getB() const;
float getC() const;
// mutators
void setCoefficients(float coA, float coB, float coC);
// rest of class definition as in question...
}; // end of class declaration
Quadratic & operator+(const Quadratic & q1, const Quadratic & q2);
Quadratic & operator*(double r, const Quadratic & q);
Overloading operators can cause subtle bugs. I strongly urge you to read this page to avoid the common pitfalls:
Operator overloading
Looks like you are re declaring your whole class. In C++, you say class once to declare the interface (usually in the h file), and then go about defining the methods (usually in the cpp file). By saying class in the two files you are re declaring the class instead of defining the implementation.
Also, you don't need to say Quadratic:: inside the class declaration, since the class keyword makes it where anything you declare inside it is by definition inside the class scope. In contrast, when you write your implementation, you do need to prepend Quadratic:: because you are no longer inside the class scope.
Last, you also need not "use" namespace std twice. It's enough to put it in the h file before the class declaration; it'll also be accessible from the class implementation in the cpp file because the cpp file includes the h file.
Move the operator+ and operator* functions outside of the class as John suggested. However, you've to make those functions friends of the class as you need access to the private variables of the objects.
Additionally, you've declared the operator functions as returning references, but for the syntax you need q3 = q1 + q2;, you've to return by value after constructing a new object. So after removing the current operator+ and operator* functions, you've to do
class Quadratic
{
. . .
friend Quadratic operator+ (const Quadratic &lhs, const Quadratic &rhs);
friend Quadratic operator+ (double scalar, const Quadratic &rhs);
}
Quadratic operator+ (const Quadratic &lhs, const Quadratic &rhs)
{
Quadratic result;
result.setCoefficients(lhs.a + rhs.a, lhs.b + rhs.b, lhs.c + rhs.c);
return result;
}
If you made your constructor like this
Quadratic::Quadratic(float coA = 0.f, float coB = 0.f, float coC = 0.f) :
a(coA),
b(coB),
c(coC),
x()
{
}
i.e. with default arguments, you can write the operator function in a single line:
Quadratic operator+ (const Quadratic &lhs, const Quadratic &rhs)
{
return Quadratic(lhs.a + rhs.a, lhs.b + rhs.b, lhs.c + rhs.c);
}
This will facilitates return value optimization (RVO) which will avoid copies. Also in constructors using initialization lists than member assignment is better.
The usual way is to initialize member variables (i.e. fields) in the constructor before its body:
Quadratic::Quadratic() : a(0), b(0), c(0), x(0) {};
Then I would believe the compiler would consider the fields as initialized.
(at least GCC does).
And you could declare some operators inside the class, see here:
class Quadratic {
Quadratic & operator += (const Quadratic&right);
You could declare it outside of the class, e.g.
Quadratic operator + (const Quadratic& left, const Quadratic& right);
As others told you, you probably want to return a value, not a reference.
notice that *this is the left operand, which you should usually return.
BTW, please show the exact error messages you have got, and their precise location.
I have a class
class Item {
int _one;
int _two;
int _three;
// other stuff
};
class ItemList : public std::vector<Item> {
// deriving from std vector because the ctor needs to
// perform some work in discriminating what gets added
// to the list
};
I've read many of the arguments against deriving from std::vector<> and I think I'll be ok because this class isn't to be derived from. I'm exposing this in python, using the boost vector indexing suite, to act as a python list. Because I needed the constructor to do some work in eliminating certain elements from the list during construction, I decided to go this route instead of doing what I've done elsewhere in the project:
class AnotherItem {
// class definition
};
typedef std::vector<AnotherItem> AnotherItemList
And then expose the list with boost vector indexing suite using the typedef. All seems well except that I have this error: Error 2 error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Item' (or there is no acceptable conversion)
The error isn't coming from the boost libraries but something in the std algorithm code. I've tried to added my own class overloaded == operator, but this hasn't fixed the problem. It looks like this:
class Item {
// earlier stuff
bool operator==(Item& rhs) {
return (_one == rhs._one && _two == rhs._two && _three == rhs._three);
}
bool operator!=(Item& rhs) {
return !(*this == rhs);
}
};
This hasn't fixed the issue. What am I missing? This link here shows that the == operator for vector is NOT a member function. I tried overloading at the "global" level (I.e. not within a namespace), but this didn't help either. So, what am I missing?
Thanks,
Andy
The proper overload for == is
class Item
{
...
bool operator==(const Item& rhs) const
{ .... }
bool operator!=(const Item& rhs) const
{ return !(*this==rhs); }
};
Also, be shure that, because std::vector doesn't have virtual members, your derived ItelmList cannot be used polymorphically against std::vector itself, in particular don't call delete against an std::vector*.
I have to say this because otherwise me and you will be doomed by tha C++ communinty although in 30+ year of experience in programming I never never never saw a std::vector* or an std::string*. (And hence I really don't know all the "scare" about deriving std classes is about: simply know what you are doing and let other people know)
What is the difference between these two ways of overloading the != operator below. Which is consider better?
Class Test
{
...//
private:
int iTest
public:
BOOL operator==(const &Test test) const;
BOOL operator!=(const &Test test) const;
}
BOOL operator==(const &Test test) const
{
return (iTest == test.iTest);
}
//overload function 1
BOOL Test::operator!=(const &Test test) const
{
return !operator==(test);
}
//overload function 2
BOOL Test::operator!=(const &Test test) const
{
return (iTest != test.iTest);
}
I've just recently seen function 1's syntax for calling a sibling operator function and wonder if writing it that way provides any benefits.
Your first overload ensures that calling != on your type will always provide the opposite of calling == even if your implementation of == would change.
Your second overloaded function does not, since it is possible to provide any implementation for == and change the existing implementation in the future.
If you want to ensure that != will always be the opposite of ==, go with the first (at the cost of an extra function call which may very well become inlined anyway).
Here is a good example. Suppose that you have a class Point2D with fields x and y. If you want to implement ==, you will have to compare on field x and on field y. If you implement != by calling operator==, you have shorter code, and will have one function less to change if you ever moved to a polar representation.
Equality tests and comparisons are always susceptible to maintenance errors as the class fields change. Minimizing the number of methods that directly access state can reduce the risk of errors.
They will almost certainly compile to the same machine code.
I prefer choice 2, just because I find it awkward to say "operator==". But you could have used
return ! (*this == test)
And IMHO that's also clear and easy to understand.
I can think of many reasons (or perhaps aspects of the same reason) to write it that way. What they all boil down to is: it's DRY.
It ensures that two objects are always either == or !=
If you decide to change what's in the class, or what's used for equality testing, you only have to change it in one place
I think that conceptually, you really have two different things you're defining here:
A definition of "equality" for class Test
A useful interface by which people using this class can determine equality of their instances
With method 2, you're doing both ad-hoc. With method 1, you're defining equality in operator==, and providing the rest of the interface via operator!=.
Some languages/libraries take it even further, e.g., in Ruby you can define just <=> to compare ordered objects and mix-in Comparable and get equality, inequalities, and between?.
Version #1, while syntacticly ugly IMHO, allows you to change the equality logic in a single place (in the == operator overload). It guarantees the two overloads are always in sync.
In general, the following statement:
return !(*this == object);
allows you to define != in terms of one function. In the world of inheritance, child objects would only need to define operator== in order to use the base class operator!=:
struct Base
{
virtual bool isEqual(const Base& other) const = 0;
bool operator==(const Base& other) const
{
return isEqual(other);
}
bool operator!=(const Base& other) const
{
return !(*this == other); // Uses Base::operator==
}
};
With the above base class, defining operator!= using != would require descendants to implement more methods.
Also, !(*this == other) allows one to define a global, generic function for !=:
template <typename T>
bool operator!=(const T& a, const T& b)
{
return !(a == b);
}
Although this pattern doesn't provide much for == and !=, the differences are larger when using the relational operators: <, <=, >, >=.
In general, it is always better to implement related functionality in terms of each other. In case of operators, there are always groups. For example, != can be implemented in terms of ==; post-increment can be implemented in terms of pre-increment; >, <= and >= can be implemented in terms of < (see std::rel_ops in <utility>) etc. If something about the class needs changing, you only need to modify the core operators, and all the rest will automatically be updated to reflect the new behavior.
The general implementation of all the "secondary" operators is always the same, and so there is even a library which automatically provides operators that are defined in terms of a few provided ones. See Boost.Operators
Your example:
#include <boost/operators.hpp>
class Test : boost::equality_comparable<Test, Test>
{
private:
int iTest;
public:
bool operator==(const Test& test) const;
//look, no operator !=
};
int main()
{
Test a, b;
a != b; //still works
}