How can I have both conversion constructor and conversion operator? - c++

Consider this simple C++-17 program:
#include <iostream>
#include <math.h>
using namespace std;
class Fraction {
public:
int nom;
int den;
Fraction operator+ (const Fraction& other) {
int nn = nom * other.den +
den * other.nom;
int dd = den * other.den;
return Fraction(nn, dd);
}
Fraction(int nn, int dn): nom(nn), den(dn) { }
Fraction(int nn): nom(nn), den(1) { }
operator double() const { return double(nom) / den; }
};
ostream& operator<<(ostream& os, const Fraction& frac) {
return os << frac.nom << '/' << frac.den;
}
int main() {
Fraction f1(1, 4);
cout << "f1 = " << f1 << endl << "f1+2 = " << (f1 + 2) << endl;
return 0;
}
This program yields a compilation error:
main.cpp:35:52: error: use of overloaded operator '+' is ambiguous (with operand types 'Fraction' and 'int')
cout << "f1 = " << f1 << endl << "f1+2 = " << (f1 + 2) << endl;
~~ ^ ~
main.cpp:17:11: note: candidate function
Fraction operator+ (const Fraction& other) {
^
main.cpp:35:52: note: built-in candidate operator+(double, int)
cout << "f1 = " << f1 << endl << "f1+2 = " << (f1 + 2) << endl;
^
However, if I remove either the conversion constructor "Fraction(int nn): nom(nn), den(1) { }" or the conversion operator "operator double() const { return double(nom) / den; }", the program runs fine.
I want to convert both to and from Fraction. What can I do to have both conversions and still have the program compile?

From the error, the compiler is complaining as it can't resolve the ambiguity on its own. As it correctly points out there are 2 possible solutions and it doesn't know which one to pick without additional insight from you.
How would you like (f1 + 2) evaluated, if you want Fraction addition, recommend changing caller to (f1 + Fraction(2)).
If you instead want double addition, change it to (double(f1)+2).
Bottom line, you can continue to have both conversion from fraction to double & integer to fraction construction, but you will need to explicitly specify the behavior you want when there is ambiguity for the compiler.

Make one or both conversion functions explicit. That will prevent your friendly compiler from implicitly using them when choosing an overload of operator + based on implicit conversions sequences.
explicit Fraction(int nn): nom(nn), den(1) { }
explicit operator double() const { return double(nom) / den; }
Just bear in mind it prevents all uses of those functions for implicit conversions.

Related

Overloading the assignment operator= doesn't work for anything except the implicit object passed in c++

The comparison in the assignment operator works as expected, but when I try to use a temp variable and load then return that, all it returns is the defaults. Debugs show that the values are default 1 x 4, but I'm not sure what to with it to make it fill the temp variables and return them. Everything I've gone through says it should work.
Debug info:
- poly {coefficient="2" variable="x" exponent="4" } Polynomial
+ coefficient "2" std::string
+ variable "x" std::string
+ exponent "4" std::string
- poly2 {coefficient="3" variable="x" exponent="4" } Polynomial
+ coefficient "3" std::string
+ variable "x" std::string
+ exponent "4" std::string
- poly3 {coefficient="1" variable="x" exponent="4" } Polynomial
+ coefficient "1" std::string
+ variable "x" std::string
+ exponent "4" std::string
main
// Demonstrating class Polynomial's overloaded stream insertion
// and stream extraction operators.
#include <iostream>
#include "Polynomial.h"
using namespace std;
int main() {
Polynomial poly; // create object poly
Polynomial poly2; // create object poly
Polynomial poly3; // create object poly
Polynomial poly4; // create object poly
Polynomial poly5; // create object poly
cout << "Enter polynomial number in the form 2x4:" << endl;
// cin >> phone invokes operator>> by implicitly issuing
// the non-member function call operator>>(cin, phone)
cin >> poly;
cout << "\nThe polynomial number entered was:\n";
// cout << phone invokes operator<< by implicitly issuing
// the non-member function call operator<<(cout, phone)
cout << poly << endl;
cout << "Enter polynomial number in the form 2x4:" << endl;
// cin >> phone invokes operator>> by implicitly issuing
// the non-member function call operator>>(cin, phone)
cin >> poly2;
cout << "\nThe polynomial number entered was:\n";
// cout << phone invokes operator<< by implicitly issuing
// the non-member function call operator<<(cout, phone)
cout << "poly2 " << poly2 << endl;
poly3 = poly + poly2;
cout << "poly3 " << poly3 << endl;
poly4 = poly - poly2;
cout << "poly4 " << poly4 << endl;
poly5 = poly;
cout << "poly5 " << poly5 << endl;
}
Header
#pragma once
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include <iostream>
#include <string>
class Polynomial {
friend std::ostream& operator<<(std::ostream&, const Polynomial&);
friend std::istream& operator>>(std::istream&, Polynomial&);
public:
// Default Constructor
Polynomial(std::string coefficient = "1", std::string variable = "x",
std::string exponent = "4");
// Copy Constructor
Polynomial(const Polynomial& copy)
: coefficient{ copy.coefficient }, variable{ copy.variable },
exponent{ copy.exponent } {
std::cout << "Copy Constructor called" << std::endl;
}
void setPolynomial(std::string, std::string, std::string);
Polynomial getPolynomial();
// addition operator; Polynomial + Polynomial
Polynomial operator+(const Polynomial&) const;
// subtraction operator; Polynomial - Polynomial
Polynomial operator-(const Polynomial&) const;
// assigment operator; Polynomial - Polynomial
Polynomial operator=( Polynomial&);
private:
std::string coefficient; //
std::string variable; //
std::string exponent; //
};
#endif
Polynomial.cpp
// Overloaded stream insertion and stream extraction operators
// for class PhoneNumber.
#include "Polynomial.h"
#include <iomanip>
using namespace std;
// default constructor; conversion constructor that converts
Polynomial::Polynomial(std::string co, std::string va, std::string ex) {}
// Setters
void Polynomial::setPolynomial(std::string co, std::string va, std::string ex) {
this->coefficient = co;
this->variable = va;
this->exponent = ex;
}
// Getters
Polynomial Polynomial::getPolynomial() { return *this; }
// overloaded stream insertion operator; cannot be a member function
// if we would like to invoke it with cout << somePhoneNumber;
ostream& operator<<(ostream& output, const Polynomial& number) {
output << "Coefficient: " << number.coefficient
<< "\nVariable: " << number.variable
<< "\nExponent: " << number.exponent << "\n"
<< "" << number.coefficient << "" << number.variable << "^"
<< number.exponent << "\n";
return output; // enables cout << a << b << c;
}
// overloaded stream extraction operator; cannot be a member function
// if we would like to invoke it with cin >> somePhoneNumber;
istream& operator>>(istream& input, Polynomial& number) {
input >> setw(1) >> number.coefficient; // input area code
input >> setw(1) >> number.variable; // input exchange
input >> setw(1) >> number.exponent; // input line
return input; // enables cin >> a >> b >> c;
}
// addition operator; Polynomial + Polynomial
// A member function takes an implicit first parameter
Polynomial Polynomial::operator+(const Polynomial& op1) const {
Polynomial temp; // temporary result
if (this->variable == op1.variable) {
if (this->exponent == op1.exponent) {
// Use stoi string to int
int num1 = stoi(this->coefficient);
int num2 = stoi(op1.coefficient);
// use to_string to set coefficient
std::string s = std::to_string(num1 + num2);
temp.coefficient = s;
temp.variable = this->variable;
temp.exponent = this->exponent;
}
else {
std::cout << "Exponents must match\n";
}
}
else {
std::cout << "Variables must match\n";
}
return temp; // return copy of temporary object
}
// substraction operator; Polynomial - Polynomial
// A member function takes an implicit first parameter
Polynomial Polynomial::operator-(const Polynomial& op1) const {
Polynomial temp; // temporary result
if (this->variable == op1.variable) {
if (this->exponent == op1.exponent) {
// Use stoi string to int
int num1 = stoi(this->coefficient);
int num2 = stoi(op1.coefficient);
// use to_string to set coefficient
std::string s = std::to_string(num1 - num2);
temp.coefficient = s;
temp.variable = this->variable;
temp.exponent = this->exponent;
}
else {
std::cout << "Exponents must match\n";
}
}
else {
std::cout << "Variables must match\n";
}
return temp; // return copy of temporary object
}
// assignment operator; Polynomial - Polynomial
// A member function takes an implicit first parameter
Polynomial Polynomial::operator=(Polynomial& op1){
// self assignment guard
if (this == &op1) {
return *this;//This returns as expected.
//
} // This should create a new temp, assign the second's info to it and return it.
// But all it does is return the default constructor values 1x4
Polynomial temp;
temp.coefficient = op1.coefficient;
temp.variable = op1.variable;
temp.exponent = op1.exponent;
return temp;
}
Polynomial.cpp:
Polynomial Polynomial::operator=( Polynomial op1) {
// self assignment guard
if (this == &op1) {
return *this;
// Do the copy
}
Polynomial temp;
this->coefficient = op1.coefficient;
this->variable = op1.variable;
this->exponent = op1.exponent;
return temp;
}
Polynomial.h
Polynomial operator=( Polynomial) ;
Your operator= makes no sense. There are two reasonable ways to implement operator=:
Using the copy-and-swap idiom, where the prototype for Polynomial would be:
Polynomial& operator=(Polynomial other);
//^^^^^^^^^^^ Returns a reference
^^^^^^^^^^ Receives argument by value
or,
"The hard way" (reimplementing stuff swap could do for you, and possibly implementing two different versions, one for copy assignment, and an optional one for move assignment), where the prototypes are:
Polynomial& operator=(const Polynomial& other);
//^^^^^^^^^^^ Returns a reference
^^^^^^^^^^^^^^^^^ Receives argument by const reference for copying
Polynomial& operator=(Polynomial&& other);
//^^^^^^^^^^^ Returns a reference
^^^^^^^^^^^^ Receives argument by r-value reference for moving
and both versions need to handle the possibility of self-assignment, manually implement the individual copies/moves, etc., or
The correct way for non-resource managing classes, follow the Rule of Zero: Every class should either manage an unmanaged resource (and nothing else), providing a copy constructor, assignment operator and destructor (in C++11, adding a move constructor and move assignment operator) or use solely managed resources and provide none of the above; the compiler will generate good ones for you.
Your original code was clearly going for option #2; your answer uses option #1's prototype, while still following option #2's template (involving a pointless self-assignment check), and on top of that, it does a crazy thing of not returning a reference to the object just assigned to (instead returning a temporary object that is never initialized to anything useful, and has nothing to do with any of the objects involved).
The minimalist solution here is to just fix your operator= for option #2 (since you've been told you should do a self-assignment check, and this is the only design that needs one):
Polynomial.cpp:
Polynomial& Polynomial::operator=(const Polynomial& op1) { // Changed to return by reference, and accept by const reference
// self assignment guard
if (this == &op1) {
return *this;
}
// No need to declare Polynomial temp; the target of the assignment is *this, the source is op1, there's no reason for a third unrelated Polynomial
this->coefficient = op1.coefficient;
this->variable = op1.variable;
this->exponent = op1.exponent;
return *this; // Returning *this by reference adheres to the protocol; you've just assigned, and the result of the expression is the object assigned to
}
Polynomial.h
Polynomial& operator=(const Polynomial&); // Same change as in .cpp, to return by ref, accept by const ref
That said, this is a silly solution. Your Polynomial contains nothing but std::string (and logically seems to have no reason for anything but variable to even be that; both coefficient and exponent seem like they should be an integer, floating point, or complex type, depending on use case), which is a managed type; adhering to the Rule of Zero would mean your class needn't implement copy assignment at all, nor copy construction, move construction, move assignment or a destructor, C++ would generate them all for you, simplifying your class to just:
Polynomial.h (now with nothing but the "from components" constructor and no assignment operators, because C++ makes them for you):
#pragma once
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include <iostream>
#include <string>
class Polynomial {
friend std::ostream& operator<<(std::ostream&, const Polynomial&);
friend std::istream& operator>>(std::istream&, Polynomial&);
public:
// Default Constructor
Polynomial(std::string coefficient = "1", std::string variable = "x",
std::string exponent = "4");
void setPolynomial(std::string, std::string, std::string);
Polynomial getPolynomial();
// addition operator; Polynomial + Polynomial
Polynomial operator+(const Polynomial&) const;
// subtraction operator; Polynomial - Polynomial
Polynomial operator-(const Polynomial&) const;
private:
std::string coefficient; //
std::string variable; //
std::string exponent; //
};
#endif
Polynomial.cpp:
// Overloaded stream insertion and stream extraction operators
// for class PhoneNumber.
#include "Polynomial.h"
#include <utility> // For std::move
#include <iomanip>
using namespace std;
// default constructor; conversion constructor that converts
// Changed: Added actual initialization of fields from arguments (previously unused)
Polynomial::Polynomial(std::string co, std::string va, std::string ex) : coefficient(std::move(co)), variable(std::move(va)), exponent(std::move(ex)) {}
// Setters
void Polynomial::setPolynomial(std::string co, std::string va, std::string ex) {
// Changed: Using std::move since we received by value, so we can empty
// large strings more efficiently by transferring ownership from the copies that
// are about to go away anyway
this->coefficient = std::move(co);
this->variable = std::move(va);
this->exponent = std::move(ex);
}
// Getters
// Note: This function makes no sense; it's basically equivalent to just using the
// copy constructor, so if you have Polynomial a and b:
// a = b.getPolynomial();
// is just a long-winded way to spell:
// a = b;
// (and it won't work if b is const, because the function wasn't declared const)
Polynomial Polynomial::getPolynomial() { return *this; }
// overloaded stream insertion operator; cannot be a member function
// if we would like to invoke it with cout << somePhoneNumber;
ostream& operator<<(ostream& output, const Polynomial& number) {
output << "Coefficient: " << number.coefficient
<< "\nVariable: " << number.variable
<< "\nExponent: " << number.exponent << "\n"
<< "" << number.coefficient << "" << number.variable << "^"
<< number.exponent << "\n";
return output; // enables cout << a << b << c;
}
// overloaded stream extraction operator; cannot be a member function
// if we would like to invoke it with cin >> somePhoneNumber;
istream& operator>>(istream& input, Polynomial& number) {
input >> setw(1) >> number.coefficient; // input area code
input >> setw(1) >> number.variable; // input exchange
input >> setw(1) >> number.exponent; // input line
return input; // enables cin >> a >> b >> c;
}
// addition operator; Polynomial + Polynomial
// A member function takes an implicit first parameter
Polynomial Polynomial::operator+(const Polynomial& op1) const {
Polynomial temp; // temporary result
if (this->variable == op1.variable) {
if (this->exponent == op1.exponent) {
// Use stoi string to int
int num1 = stoi(this->coefficient);
int num2 = stoi(op1.coefficient);
// use to_string to set coefficient
// Changed: Assigning result of std::to_string to coefficient directly
// avoiding temporary std::string s that would just add more copy/move work
temp.coefficient = std::to_string(num1 + num2);
temp.variable = this->variable;
temp.exponent = this->exponent;
}
else {
std::cout << "Exponents must match\n";
}
}
else {
std::cout << "Variables must match\n";
}
return temp; // return copy of temporary object
}
// substraction operator; Polynomial - Polynomial
// A member function takes an implicit first parameter
Polynomial Polynomial::operator-(const Polynomial& op1) const {
Polynomial temp; // temporary result
if (this->variable == op1.variable) {
if (this->exponent == op1.exponent) {
// Use stoi string to int
int num1 = stoi(this->coefficient);
int num2 = stoi(op1.coefficient);
// Changed: Assigning result of std::to_string to coefficient directly
// avoiding temporary std::string s that would just add more copy/move work
temp.coefficient = std::to_string(num1 - num2);
temp.variable = this->variable;
temp.exponent = this->exponent;
}
else {
std::cout << "Exponents must match\n";
}
}
else {
std::cout << "Variables must match\n";
}
return temp; // return copy of temporary object
}
Try it online!
Additional notes:
As written, failed + and - operations (due to mismatched variable/exponent) still behave as if they succeeded, returning a default initialized Polynomial. Sure, it dumps a log to std::cout, but the program still continues running with total garbage data. Those std::cout errors should really be exceptions, not simple logs.
Your comments claim the + and - operations return a copy of temp. While logically this true (it must be copyable to be used in that context), in most C++11 and later compilers, copy elision will occur (the new Polynomial will be constructed directly into the caller allocated storage; no moves, let alone copies will occur).

Why the code doesn't work on CodeBlocks,but on VS works

This line:
"friend ostream& operator<<(ostream& os, Fraction&& obj)"
It works on Visual Studio,But on CodeBlocks it doesn't work.
and the error is "expected ',' or '...' before '&&' token|"
#include <iostream>
#include <cstdio>
using namespace std;
int lcf(int n, int m)
{
if (n < m)
{
int tmp = n;
n = m;
m = tmp;
}
if (n % m == 0)
return m;
else
return lcf(m, n % m);
}
class Fraction
{
private:
int fenzi, fenmu;
public:
Fraction(int a, int b) :fenzi(a), fenmu(b) {}
Fraction operator+(Fraction& another)
{
fenzi += another.fenzi;
fenmu += another.fenmu;
return *this;
}
Fraction operator*(Fraction& another)
{
fenzi *= another.fenzi;
fenmu *= another.fenmu;
return *this;
}
operator double()
{
return 1.0* fenzi / fenmu;
}
friend istream& operator>>(istream& is, Fraction& obj)
{
is >> obj.fenzi;
getchar();
is >> obj.fenmu;
return is;
}
friend ostream& operator<<(ostream& os, Fraction&& obj)
{
int t = lcf(obj.fenzi, obj.fenmu);
obj.fenzi /= t;
obj.fenmu /= t;
os << obj.fenzi << "/" << obj.fenmu;
return os;
}
Fraction& operator++()
{
fenzi++;
fenmu++;
return *this;
}
Fraction operator++(int)
{
Fraction tmp(fenzi, fenmu);
fenzi++;
fenmu++;
return tmp;
}
};
int main()
{
Fraction a1(9, 11), a2(1, 2);
cout << double(a2) << endl;
cout << ++a1 << endl;
cout << a2++ << endl;
cout << a1 * a2 << endl;
return 0;
}
if the code is:
"friend ostream& operator<<(ostream& os, Fraction& obj)"
in the main function,"cout << a1 * a2 << endl" will strangely call the "operator double()" function instead of "friend ostream& operator<<()".
So I add an "&"(Fraction&& obj),and successfully work on Visual Studio as what I expected.But CodeBlocks has error.How can I solve it.
cout << ++a1 << endl;//(1)
cout << a2++ << endl;//(2)
cout << a1 * a2 << endl;//(3)
Results in Fraction& so it can bind to Fraction& or const Fraction& but not Fraction&&. Compiler is allowed one implicit user-defined conversion, so as a last attempt to make the code compile it converts to double and uses operator<<(ostream&,double&&) or operator<<(ostream&,double) not sure which is defined but the output is the same.
cout << a2++ << endl; Results in Fraction so it can bind to Fraction&& or const Fraction& but not Fraction&. operator<<(ostream&,Fraction&&) is called.
cout << a1 * a2 << endl; Results in Fraction so same as previous.
You should almost never have print with side-effects. Certainly not the ones that modify the object you passed. Then someone will write a code like this and the poor soul will spend unnecessary time with a debugger:
Fraction a;
Fraction b = a;
if(debug_build)
cout <<"LOG:"<<a<<'\n';
assert(a==b);
My solution would be:
friend ostream& operator<<(ostream& os, const Fraction& obj)
{
int t = lcf(obj.fenzi, obj.fenmu);
os << obj.fenzi/t << "/" << obj.fenmu/t;
return os;
}
Eveything can bind to const Fraction& and it's const as it should be. (1),(2),(3) will work and none will call double(). I would even consider making double() explicit as it will forbid these unexpected calls that got you confused. Unless you have good reason not to and some extra typing might not qualify.
The last thing would be to really encourage you to be const-correct and not make unnecessary copies.
Fraction& operator+(const Fraction& another)
Fraction& operator+(const Fraction& another)
Fraction operator++(int) const
Not sure what's tripping CodeBlocks as you did not post the error message. I would guess that you must enable c++11.

Addition of complex numbers using classes

I am trying to add 2 complex numbers together, but i am getting the errors:
no operator "+" matches these operands
no operator "<<" matches these operands
#include <iostream>
using namespace std;
class complex
{
public:
double get_r() { return r; }
void set_r(double newr) { r=newr; }
double set_i() { return i; }
void set_i(double newi) { i = newi; }
private:
double r, i;
};
int main()
{
complex A, B;
A.set_r(1.0);
A.set_i(2.0);
B.set_r(3.0);
B.set_i(2.0);
complex sum = A+B;
cout << "summen er: " << sum << endl;
system("PAUSE");
return 0;
};
I'm very new to programming, but i can't see why it won't add these numbers together. What have I done wrong?
You must overload operators + and << (and each one in your need) for your defined classes. Note that operators are no more than specific functions with specific definition syntax (operator+, for example: C = A + B could be understood as C = A.sum(B)). Here a link about http://en.cppreference.com/w/cpp/language/operators
Operator + is defined for builtin types and for some types from the standard library. As complex is here a custom class, you must define all operators that should act on it.
operator + could be defined as:
class complex {
...
complex operator + (const complex& other) {
return complex(get_r() + other.get_r(), get_i() + other.get_i());
}
...
};
Beware that does allow neither A++ nor A-B. They would require (resp.) complex & operator ++() or complex operator - (const complex &).
For stream insertion, the first parameter is the stream itself, so you must define a friend operator with 2 parameters outside the class:
outstream& opererator << (outstream &out, const complex& val) {
// output it the way you want
return out;
}
Complex numbers are part of the C++ standard. Here is the example from http://en.cppreference.com/w/cpp/numeric/complex.
#include <iostream>
#include <iomanip>
#include <complex>
#include <cmath>
int main()
{
using namespace std::complex_literals;
std::cout << std::fixed << std::setprecision(1);
std::complex<double> z1 = 1i * 1i;
std::cout << "i * i = " << z1 << '\n';
std::complex<double> z2 = std::pow(1i, 2);
std::cout << "pow(i, 2) = " << z2 << '\n';
double PI = std::acos(-1);
std::complex<double> z3 = std::exp(1i * PI);
std::cout << "exp(i * pi) = " << z3 << '\n';
std::complex<double> z4 = 1. + 2i, z5 = 1. - 2i;
std::cout << "(1+2i)*(1-2i) = " << z4*z5 << '\n';
}
Trying to implement a class complex yourself would require you define addition, equality, and ostream. And you would only have 5% of a fully implemented class. Looking at the header itself will reveal how those that wrote the C++ standard library implemented the whole thing.
All the arithmetic operators like plus, minus, multiply or divide only work with pre defined data types, like int, char, float etc.
Now if you want to add something in a class, you have to use the fundamental aspect of OO programming that is operator overloading.
Here is how you can achieve it.
#include <iostream>
using namespace std;
class complex
{
float x, y;
public:
complex()
{
}
complex(float real, float img)
{
x = real;
y = img;
}
friend complex operator+(complex,complex);
void display(void);
};
complex operator+(complex c,complex d)
{
complex t;
t.x = d.x + c.x;
t.y = d.y + t.y;
return(t);
};
void complex::display(void)
{
cout << x << "+i" << y << endl;
}
int main()
{
complex c1, c2, c3;
c1 = complex(2.5, 3.5);
c2 = complex(1.5, 5.5);
c3 = c1 + c2;//c3=opra+(c1,c2)
cout << "C1:" << endl;
c1.display();
cout << "C2:" << endl;
c2.display();
cout << "C3:" << endl;
c3.display();
}

Why overloaded operator << works sometimes but other times doesn't

I don't know why cout << da << '\n' works fine,but std::cout << next_Monday(da) << '\n' went wrong. Why the direct Date object can output, but the return Date can't.
Why overloaded operator << works sometimes but other times doesn't.
here is my code..
#include <iostream>
#include <stdlib.h>
struct Date {
unsigned day_: 5;
unsigned month_ : 4;
int year_: 15;
};
std::ostream& operator<<(std::ostream& out,Date& b)
{
out << b.month_ << '/' << b.day_ << '/' << b.year_;
return out;
}
std::istream& operator>>(std::istream& in,Date& b);
Date next_Monday(Date const &d);
int main()
{
Date da;
std::cin >> da;
std::cout << da << '\n';
std::cout << next_Monday(da) << '\n';
return 0;
}
this is what clang said: (I use g++ to invoke)
excercise19DateManipulate.cpp:114:18: error: invalid operands to binary
expression ('ostream' (aka 'basic_ostream<char>') and 'Date')
std::cout<< next_Monday(da) <<'\n';
~~~~~~~~^ ~~~~~~~~~~~~~~~
Because you can't bind a temporary to a non-const lvalue reference. Change the operator to take a const reference:
std::ostream& operator<<(std::ostream& out, const Date& b)
You never defined the "next_Monday()" function as far as I can see, you only declared it.

how to implement complx class and implementing arithmetic functions

I am working on my assignment right now which wants me to implement complx class and also put in missing arithmetic operators, he gave us the addition one and im sure i have the subtraction and multiplication ones right but im messing up on the operator+ with double part, also not sure with the operator==. Very new to programming so if you see anything else wrong or could be improved please say so. here is the header
// Complx.h
#include <iostream>
#include <fstream>
using namespace std;
class complx
{
public:
double real,
imag;
complx( double real = 0., double imag = 0.); // constructor
complx operator+(complx); // operator+()
complx operator+(double); // operator+()with double
complx operator- (complx); // operator-()
complx operator* (complx); // operator*()
bool operator== (complx); // operator==()
//Sets private data members.
void Set(double new_real, double new_imaginary) {
real = new_real;
imag = new_imaginary;
}
//Returns the real part of the complex number.
double Real() {
return real;
}
//Returns the imaginary part of the complex number.
double Imaginary() {
return imag;
}
};
ostream &operator << ( ostream &out_file, complx number );
extern istream &operator >> ( istream &in_file, complx &number );
extern ifstream &operator >> ( ifstream &in_file, complx &number );
complx &operator + (double, complx);
complx &operator - (double, complx);
complx &operator * (double, complx);
my complex.cpp file
// Complx.cpp
#include "complx.h"
#include <iostream>
extern ifstream &operator >> ( ifstream &in_file, complx &number )
{
double re, is;
char ch;
if (in_file >> ch && ch == '('&& in_file >> re >> ch && ch == ','
&& in_file >> is >> ch && ch == ')')
number.Set(re,is);
else cerr << "Finish the input"<<endl;
return in_file;
}
ostream &operator<< ( ostream &out_file, complx number )
{
out_file << '(' << number.Real() << ',' << number.Imaginary() << ')';
return out_file;
}
// define constructor
complx::complx( double r, double i )
{
real = r; imag = i;
}
// define overloaded + (plus) operator
complx complx::operator+ (complx c)
{
complx result;
result.real = (this->real + c.real);
result.imag = (this->imag + c.imag);
return result;
}
//define overloaded double + operator
complx operator+(const double&, const complx& c)
{
complx operator+(const double&, const complx& c)
{
complx result;
result.real = (double real + c.real);
result.imag = (this->imag + c.imag);
return result;
}
// define overloaded - operator
complx complx::operator- (complx c)
{
complx result;
result.real = (this->real - c.real);
result.imag = (this->imag - c.imag);
return result;
}
//define overloaded * operator
complx complx::operator* (complx c)
{
complx result;
result.real = (this->real * c.real);
result.imag = (this->imag * c.imag);
return result;
}
and my call_complx.cpp
//call_complx.cpp
#include "complx.h"
ifstream infile ("in.dat");
int main()
{
int i=0;
complx in[7];
double d = 4.5;
cout<< "The input numbers are: " << endl;
while (infile >> in[i]){
cout << in[i] << endl;
i++;
}
complx s1 = in[0] + in[1]; // calls complx::operator+()
complx s2 = d + in[2]; // overload operator+()
complx s3 = in[3] + d; // overload operator+()
complx a = in[4] - in[5];
complx mm=in[3]*in[4];
complx dm=d*in[4] ;
complx b=d-in[0] ;
cout << "The sum is a complex number " << s1 <<endl;
cout << "The sum is a complex number " << s2 <<endl;
cout << "The sum is a complex number " << s3 <<endl;
cout << "The subtract is a complex number " << a <<endl;
cout << "The product is a complex number " << mm <<endl;
cout << "The subtract is a complex number " << b <<endl;
cout << "The product is a complex number " << dm <<endl;
if (in[4] == in[5]) cout << "in[4] and in[5] are the same " << endl;
system("pause");
return 0; //successful termination
}
this is also my first time posting here so if theres any rules and such that im not following, please pardon and enlighten my ignorance please.
I spotted some repeated declarations for operatr+ (double, complx) in your code which doesn't seem right. That is, you duplicate the declaration of the operator. Remove one copy:
complx operator+(const double&, const complx& c)
{
complx operator+(const double&, const complx& c) // <--- needs to go
{ // <--- needs to go
Ignoring that marginal detail, here are a few notes:
Generally you don't want to implement the binary arithmetic operators as members. Instead, you want to implement mutating operator using, e.g., operator+=(), operator-=(), etc. and then implement the operators in terms of these, e.g.,
complx& complx::operator+= (complx other) {
this->real += other.real;
this->imag += other.imag;
}
complx operator+ (complx c0, complx c1) {
return c0 += c1;
}
Your multiplication is definitely wrong: According to your implmenetation i2 == i but it should be -1. For the multiplication (and division) it is definitely not sufficient to do memberwise operations. Instead, the result is (a + bi) (c + di) == (ac - bd) + (ad + bc)i which is of course more ore less the normal distributivity applies with observing that i2 == -1.
The neat aspect of using non-member binary operators with classes supporting implicit conversions is that you don't need to be bothered at all about the mixed type version: the implicit conversions play nicely with these operators. Of course, you can still implement the mixed type operators but you are probably best off to implement the logic just once and delegate to an already implemented operator, e.g.:
complx operator+ (double d, complx c) {
return complx(d) + c;
// or: return complx(d) += c;
}
BTW, you never want to pass built-in type by const&! Passing them by value can be more efficient.