Compound assignment operator overloading - c++

I have seen Boost give you the possibility of doing:
v*=c where c is i.e. a double and v is a vector
How could I make, as an exercise, the overloading of *= correctly, which works in the same way of the previous example (with double on the right side)?

How about something like this?
// in class
T& operator *= (double d)
{
member *= d;
return *this;
}
// outside of class
T operator * (T v, double d)
{
v *= d;
return v;
}

Your method will look as follows:
inline vector operator *= (vector v, double &b);
It's overloaded for the class vector, should take a double, should modify the object itself and should return itself to be used as v1 = v2*= 4.2;
Since it's for an exercise, you won't post the implementation here.

Related

How to use some class in paramater template other class?

I have two classes Polynom and Fraction.
I need to do a template for Polynom, for using Fraction like coefficient in Polynom, like: 3/4 x^0 + 5\6 x^1 etc.
I understood how to use a simple type like double or int, but how to get this to work for a class I have no idea, and can't find a material on this theme.
class Fraction {
private:
int numerator, denominator;
public:
Fraction();
Fraction(int, int);
Fraction(int);
}
template<class T>
class PolynomT {
private:
int degree;
T *coef;
public:
PolynomT();
explicit PolynomT(int, const T * = nullptr);
~PolynomT();
};
template<class T>
PolynomT<T>::PolynomT(int n, const T *data): degree(n) {
coefA = new T[degree+1];
if (data == nullptr) {
for (int i = 0; i < degree+1; ++i)
coefA[i] = 0.0;
}
else {
for (int i = 0; i < degree + 1; ++i)
coefA[i] = data[i];
}
}
/*Problem here*/
int main() {
PolynomT<Fraction> a(); // what need to pass on here in arguments?
// how should the constructor look like?
/*Example*/
PolynomT<Fraction> b();
PolynomT<Fraction> c = a + b; // or something like this.
}
So, how to do the class constructor for Fraction in PolynomT, and how to do overloading operators for this?
The problem with the coefA[i] = 0.0 assignment in the PolynomT constructor happens because Fraction does not have a constructor that takes a double, nor does it have an assignment operator that takes a double. There are several possible solutions.
Change from raw memory management to std::vector for coefA.
std::vector<T> coefA;
// Then resize appropriately in the constructor
This would automatically fill all the elements with a default constructed object, so you wouldn't need to do anything if data == nullptr.
Another possibility is to change the assignment to
coefA[i] = T();
This will assign a default constructed object of the type (0.0 for doubles).
What are the basic rules and idioms for operator overloading has detailed information on overloading operators.

overloading operator for linear algebra

I want to implement the Euler method in two dimensions and I don´t want to use any library (for practice).
Therefore I want to use my own linear algebra with overloaded functions.
The two first overloads seem to work but there´s still a problem with the multiplication matrix * vector i.e a (2x2)*(2x1).
class vector{
public:
double a;
double b;
vector::vector();
vector::vector(double a, double b){
this->a = a;
this->b = b;
};
vector operator+(vector &a);
vector operator*(double factor);
vector operator*(matrix &B);
};
class matrix{
public:
double a1;
double a2;
double b1;
double b2;
matrix::matrix();
matrix::matrix(double a1, double a2, double b1, double b2) {
this->a1 = a1;
this->a2 = a2;
this->b1 = b1;
this->b2 = b2;
};
};
vector vector::operator+(vector& v){
return vector(this->a+v.a,this->b+v.b);
};
vector vector::operator*(double factor){
return vector(this->a*factor, this->b*factor);
};
vector vector::operator*(matrix& B){
vector newv(this->a*B.a1 + B.a2*b, this->a*B.a1 + B.b2*b);
return newv;
};
Errors when I compile it:
'vector vector::operator *(matrix &)' : overloaded member function not found in 'vector'
unable to resolve function overload
Since you're a bit short on details, I must fill in the gap with guesses. My guess is that you try to support something like the following:
matrix m;
vector v, w;
// fill m and v with values
w = m*v;
I'm also guessing that your matrix has the following form:
( a1 a2 )
( b1 b2 )
You now have two options: Either implement matrix-vector multiplication in the class matrix, or implement it as a free function.
If you want to put if in the matrix class, you'd change the code as follows (note that there are many more things for the code that should be changed, but those are unrelated to the question):
class vector
{
// omit the operator* for matrix, otherwise unchanged
};
class matrix
{
// all that's already in the class
vector operator*(vector const& v) const;
};
vector matrix::operator*(vector const& v) const
{
return vector(a1*v.a + a2*v.b, b1*v.a + b2*v.b);
}
// the rest of your code
If you want to make it a free function (I personally would do it that way, but I'm sure that opinion is not universally held), you'd write
class vector
{
// omit the operator* for matrix, otherwise unchanged
};
class matrix
{
// completely unchanged
};
vector operator*(matrix const& m, vector const& v)
{
return vector(m.a1*v.a + m.a2*v.b, m.b1*v.a + m.b2*v.b);
}
// the rest of your code
I would prefer a BLAS library as an implementation in long term against reinvent the wheel again for basic matrix operations. Additionally some of the BLAS libraries are multithreaded and/or GPU based; they are widely used and tested.
In terms of design I would introduce functions what could be easily implemented by BLAS against operators:
C = α * A + β * B
C = α * A * B + β *C
So as a header:
...
bool blasAdd(const double alfa_, const Matrix& A_, const double beta_, const Matrix& B_, Matrix& C_);
bool blasMultiply(const double alfa_, const Matrix& A_, const Matrix& B_, const double beta_, Matrix& C_);
...
In this way your code automatically could be optimized for BLAS.
My favorite BLAS implementation is Intel MKL, but there are also many free BLAS implementations in the market (e.g.: boost BLAS).

Conversion by constructor doesn't work with operator overloading [duplicate]

This question already has answers here:
No implicit conversion in overloaded operator
(2 answers)
Closed 8 years ago.
Consider the code
#include <stdio.h>
class complex
{
private:
double re,im;
public:
complex(double, double);
complex(double);
complex operator+(complex c);
double getre();
double getim();
};
complex complex::operator+(complex c)
{
return *new complex(re+c.getre(),im+c.getim());
}
complex::complex(double real, double imagine)
{
re= real;
im= imagine;
}
complex::complex(double real)
{
re= real;
im=0;
}
double complex::getre()
{
return re;
}
double complex::getim()
{
return im;
}
int main()
{
complex *z= new complex(2.0);
complex *w= new complex(3.0, 4.0);
printf("%f\n",(2.0+*z).getre());//Compile error: no match for ‘operator+’ in ‘2.0e+0 + * z’
}
But if we replaced our operator member function to a non-member function like the following:
complex operator+(complex t, complex c)
{
return *new complex(t.getre()+c.getre(),t.getim()+c.getim());
}
then it works fine. But I'm expected that it will work in all descibed cases. We've defined constructor conversion as.
Binary operators don't attempt any conversion to the left side argument, the "receiver" of the function.
If you want a builtin type on the left hand side, the overload must be a free function.
The simplest way is usually to have a mutating member, += in this case, and delegate to that from the free function(s).
Something like this:
complex complex::operator+=(complex rhs)
{
re += rhs.re;
im += rhs.im;
return *this;
}
complex operator+(complex t, complex c)
{
t += c;
return t;
}
int main()
{
complex z(2.0);
complex w(3.0, 4.0);
printf("%f\n",(2.0 + z).getre());
}
You should also make your getters const.
And you receive a gold star for not having setters.

Constructing result in operator vs operating on default-constructed object

I have a class which is essentially an array with labelled contents, and I'd like to define some operators for it. I'd like to do it in such a way that changing the number of elements in the class is easy, as I expect future users will change the variables tracked, but I'd also like to ensure that basic arithmetic operations on the class are as efficient as possible.
I can see two way of implementing the operators. Taking the example of a Vector2D class:
struct Vector2D {
//members
const static int nElem = 2;
double x;
double y;
//Constructors
Vector2D() {}
Vector2D(double X, double Y) : x(X), y(Y) {}
//Operators
double& operator[] (int index) {
switch(index) {
case 0:
return x;
case 1:
return y;
default:
return std::out_of_range ("Oops");
}
}
// Option 1: operator+ by constructing result
Vector2D operator+ (const Vector2D & rhs) const {
return Vector2D(x + rhs.x, y+rhs.y);
}
// Option 2: operator+ using loop and [] operator
Vector2D operator+ (const Vector2D & rhs) const {
Vector2D result;
for(int i = 0; i < nElem; i++)
result[i] = (*this)[i] + rhs[i];
return result;
}
};
Assuming I use -03 optimization, will there be any difference between the two implementations of operator+? My understanding is that since the default Vector2D constructor has no code body and the class contents are a default data type, there is no extra overhead in Option 2 for calling the default constructor on result before setting its members. I expect the two to be equivalent, but I'm not confident enough in my knowledge to be sure.
Your method won't work at all. If you want someone to be able to change nElem you can't use x, y as your names. Why? Because changing nElem to 3 won't magically add z. And since you can't do a for loop over x and y, your definition of nElem is meaningless.
Finally, this is a textbook case for the use of a number template. Create a vector which is templated over how many elements it has.
Do something like this:
template<unsigned int LEN>
class Vector{
double v[LEN];
public:
Vector operator+(const Vector &o){
Vector res;
for (unsigned int i=0;i<LEN;++i) // with -O3 and small LEN this will be unrolled
res.v[i]=v[i]+o.v[i];
}
// ... etc.
};
Then you use it like this:
Vector<2> my_2d_vec;
Vector<3> my_3d_vec;

Overriding +/-/*/% by integer and the -Weffc++ flag

I have a class called Coord...it has instance data x, y. I want to override the * operator such that the * operator can be used to multiply the Coord by an integer or double! This is the solution I put up:
Coord& Coord::operator*(int n)
{
this->x = this->x*n;
this->y = this->y*n;
return *this;
}
It works - I've tested some print outs from main...the only issue is...I get a warning from the -Weffc++ flag! It says my function should return by value! I know this flag corresponds to the book "Effective C++" book, but I don't have a copy onhand - what does the book suggest? What is meant to pass by value?
Just to elaborate on Grizzly's comment... This is not the in-place multiplication. As such, you should declare it const to explicitly prevent that:
Coord Coord::operator*(int n) const {
Coord c(*this);
c.x *= n;
c.y *= n;
return c;
}
Or if you have a useful constructor:
Coord Coord::operator*(int n) const {
return Coord(x*n, y*n);
}
The in-place multiplication is different (and non-const):
Coord& Coord::operator*=(int n) {
x *= n;
y *= n;
return *this;
}
You haven't implemented operator* but rather you implemented the self-mutating operator*=, assigning the result back to the original object.
Consider the effects of your operator's implementation for the following int example:
int x = 5;
int y = 2;
int z = x * y;
Now, with integer multiplication implemented similarly to your code, you would end up with both y and z equal to 10.
In order to implement the normal operator* type operators you'll need to create a temporary object and return that by value.
You're probably looking for an implementation more like this (assuming you have a two parameter constructor to your class):
Coord Coord::operator*(int n) const
{
return Coord(x * n, y * n);
}
But note that often, what seems like an obvious meaning of an operator isn't so clear, and overloading simply causes confusion. Consider a non-member named function instead (using a named member scaling function), along these lines:
Coord& Coord::ScaleBy(int n)
{
this->x = this->x*n;
this->y = this->y*n;
return *this;
}
Coord ScaleCoord(Coord c, int n)
{
return c.ScaleBy(n);
}
In general, this sort of thing is done in two parts, a member operator*= and a non-member operator* that uses *=:
Coord& Coord::operator*=(int n) {
x *= n;
y *= n;
return *this;
}
Coord operator*(const Coord& c, int n) {
Coord res(c);
res *= n;
return res;
}