C++ implicit typecast - c++

I want to convert numerous similar classes into each other. They have at least a common abstract ancestor, which defines 2 basic methods.
I ran into weird typecast errors, so I made a simplified example. On top of the hierarchy: the Integer class. It's an abstract class that have an int val() method. One of it's child is just a holder for a physical int value, while the other references 2 Integers and val() is the sum of its two referenced Integers.
I wrote this code, and I could not figure why the commented expression fails to compile while using a temporary variable works just great.
class Sum;
class Integer {
public:
virtual int val(void) const = 0;
Sum operator+(Integer & other);
};
class Sum : public Integer {
private:
Integer &op1, &op2;
public:
explicit Sum(Integer &a, Integer &b) : op1(a), op2(b) {};
int val(void) const {return op1.val() + op2.val();};
};
class Int : public Integer {
private:
int v;
public:
Int(int value=0) : v(value) {};
Int(Integer & other) : v(other.val()) {};
int val() const {return v;};
Int & operator=(Integer & other){v = other.val(); return *this;};
Int & operator=(int value){v = value; return *this;};
};
std::ostream & operator<<(std::ostream & out, Integer & i){return out << i.val();}
Sum Integer::operator+(Integer & other){return Sum(*this, other);}
int main(int argc, const char **argv){
Int a=42, b=57;
// Int s = a+b; => conversion from ‘Sum’ to non-scalar type ‘Int’ requested
Sum r = a+b;
Int s = r; /* OK */
cout << a << " + " << b << " = " << s << endl;
return 0;
}

class Int : public Integer {
private:
int v;
public:
Int(int value=0) : v(value) {};
Int(Integer & other) : v(other.val()) {};
int val() const {return v;};
Int & operator=(Integer & other){v = other.val(); return *this;};
Int & operator=(int value){v = value; return *this;};
};
The constructor Int(Integer & other) doesn't modify its argument, so could (should) make that reference const:
Int(Integer const& other) : v(other.val()) {};
This also solves your problem:
Sum Integer::operator+(Integer & other);
Int s = a+b;
The operator + (which should arguably be a free function instead of a member function) returns a prvalue/temporary of type Sum. This temporary cannot bind to a non-const lvalue reference, therefore the constructor Int(Integer & other) cannot be used.
Similarly for Int & operator=(Integer & other), a const reference is sufficient.

For functions that take non-const references, like your constructor for Int, you cannot pass temporary objects. A common explanation for this is because if you a function takes a non-const reference, it is allowed to modify the referent, but with a temporary object, this change doesn't really go anywhere since the referent variable isn't accessible outside of the function call.
As DyP suggests in the comments, changing the value to const will provide a solution, or you could simply bind it to a variable like you did with 'Sum r = a+b'.

Related

'this' argument has type const but function is not marked const c++ overload operator

How do i fix this?
I'm getting error: 'this' argument has type const but function is not marked const c++ overload operator
template <class T>
class Rational {
private:
T n = 0;
T d = 1;
public:
Rational() = default;
T numerator() {
return n;
}
T denominator() {
return d;
}
};
template <class T>
inline bool const operator ==(const Rational <T> & lhs, const Rational <T>& rhs) {
return lhs.numerator() * rhs.denominator() == lhs.denominator() * rhs.numerator();
}
My guess is that numerator() and denominator() member functions are not const member functions. Make them const. After that, the above function should work.
BTW, there is no need for the return type to be bool const. Keep it simple and change it to bool.
If numerator() and denominator() are to be used to directly assign to Rationals internal member variables as well as being used in const contexts, you need two sets of overloads. One mutable and one const:
// mutable interface
T& Rational::numerator();
T& Rational::denominator();
// const interface if T may only be a fundamental integral type
T Rational::numerator() const;
T Rational::denominator() const;
// const interface if sizeof(T) may be > sizeof(T*)
T const& Rational::numerator() const;
T const& Rational::denominator() const;
Note, only one of the const interfaces may be used so you need to select one of them.
Here's an example of how it can be done:
#include <iostream>
#include <type_traits>
template<typename T>
class Rational {
public:
// pass by value for fundamental types, by const& for other types
using by_value_or_by_const_ref =
std::conditional_t<std::is_fundamental_v<T>, T, T const&>;
Rational(by_value_or_by_const_ref n, by_value_or_by_const_ref d) :
m_numerator(n), m_denominator(d) {}
// mutable interface
T& numerator() { return m_numerator; }
T& denominator() { return m_denominator; }
// const interface
by_value_or_by_const_ref numerator() const { return m_numerator; }
by_value_or_by_const_ref denominator() const { return m_denominator; }
private:
T m_numerator;
T m_denominator;
};
template<class T>
inline bool operator==(const Rational<T>& lhs, const Rational<T>& rhs) {
// using const interface
return lhs.numerator() * rhs.denominator() ==
lhs.denominator() * rhs.numerator();
}
int main() {
Rational<int> a(10, 20);
Rational<int> b(10, 10);
// using mutable interface
a.denominator() /= 4;
b.numerator() *= 2;
std::cout << std::boolalpha << (a == b) << "\n";
}

Operator overloading for add and compare data of Integer and Fraction classes

Similar to this problem posted here. I Need to create three classes:
"Number" class supports three operations,such as, “display”, “==”,
and “+”;
"Integer class" that represented by integer;
"Fraction" class is represented by numerator and denominator.
Requirements:
It should support the operations: (a) Integer (I) + Fraction (F),
(b) F+I, (c) F+F, (d) I+I, and comparing them
The caller of the + operation doesn't need to know the return type.
I could solve the problem till requirement# 1. However, couldn't figure out the second requirement yet. Any help would be appreciated.
To keep it brief, I am going to share the header file of my code below, function definition of the code can be shared if needed.
Number.h
#pragma once
template<class T>
class Number
{
public:
bool operator== (const T&)
{
return impl().operator == ();
}
T operator+ (const T &) const
{
return impl().operator+();
}
template <typename Stream>
void display(Stream& os) const
{
impl().display(os);
}
private:
T& impl() {
return *static_cast<T*>(this);
}
T const & impl() const {
return *static_cast<T const *>(this);
}
};
Integer.h
#pragma once
#include "Number.h"
class Integer : public Number<Integer>
{
int intValue{0};
public:
template <typename Stream>
void display(Stream& os) const
{
os << this->intValue << '\n';
}
Integer() = default;
~Integer() = default;
Integer(int num);
int getIntValue() const;
bool operator== (const Integer &);
Integer operator+ (const Integer &) const;
};
Fraction.h
#pragma once
#include <math.h>
#include "Number.h"
#include "Integer.h"
#include <iostream>
class Fraction : public Number<Fraction>
{
int _numerator{0};
int _denominator{1};
int gcdCalculate(int val1, int val2) const;
int lcmCalculate(const int val1, const int val2) const;
public:
template <typename Stream>
void display(Stream& os) const
{int tempNum = this->_numerator;
int tempDen = this->_denominator;
double tempFrac = (double)tempNum/(double)tempDen;
double intpart;
if (this->_denominator==0)
{
std::cout << "Undefined " << this->_numerator << "/" << this->_denominator << "(Divide by zero exception)";
}
else if (this->_denominator==1){
std::cout << this->_numerator << std::endl;
}
else {
os << this->_numerator << "/";
os << this->_denominator << '\n';}
}
Fraction() = default;
Fraction(int num, int den);
~Fraction() = default;
bool operator== (const Fraction &);
bool operator== (const Integer &);
friend bool operator== (const Integer&, const Fraction&);
Fraction operator+ (const Fraction &) const;
Fraction operator+ (const Integer &) const;
friend Fraction operator+ (const Integer&, const Fraction&);
};
main.cpp
#include <iostream>
using namespace std;
template <typename INumberType>
void GenericDisplay(const Number<INumberType>& num) //Here we are calling through the Number<> Interface
{
num.display(cout);
}
int main()
{
Fraction fracOne(1,4);
Fraction fracTwo(2,8);
Integer intOne(30);
Integer intTwo(30);
Fraction sumOfFractionOneTwo = fracOne + fracTwo;
Integer sumOfIntegerOneTwo = intOne + intTwo;
Fraction sumOfFractionOneAndIntegerOne = integerOne + fracOne;
Fraction sumOfFractionTwoAndIntegerTwo = fracTwo + intTwo;
return 0;
}
In this code, caller of the + operator knows the return type, e.g., in the int main() caller defined returned type "Fraction sumOfFractionOneAndIntegerOne = integerOne + fracOne;". Which is incorrect!
The way I want, caller should not know the return type. e.g., "Number sumOfFractionOneAndIntegerOne = integerOne + fracOne;"
Again, any help would be appreciated.
Since the type is statically known, the caller can use auto for the type of the variable, so that the type is deduced instead of explicitly specified. Otherwise, you may be looking for virtual inheritance, which allows an abstract base to be used as the type while derived classes provide implementation for further operators.

C++ - Make pointer to superclass match subclass argument in function

I've searched before asking but din't found anything working for my problem.
I would like to make a pointer to superclass (that really always refers to one of the subclasses) match a subclass argument (pointer or const reference) in a function.
Context : create an "advanced" calculator in c++.
Let me give you more details the classes being used in this issue of mine :
First we have the Literals :
class Literal {};
class IntegerLiteral : public Literal {};
class RealLiteral : public Literal {};
class RationalLiteral : public Literal {};
//....
We have a stack used to save the Literal objects by storing their adresses
// If st is instance of stack then :
st.top(); // returns a Literal*
And we have Operator objects that will interact with the stack by unstacking the correct numbers of Literal* (depending on the operator's arity), applying the operator on the Literal* objects and finally stack the result.
class Operator {
int n; // operator arity
public:
virtual void executeOperator(stack *st) = 0; //
};
One of the Operator subclass (for example) :
class PlusOperator : public Operator {
public:
virtual void execute(StackUTComputer *st) override {
Literal* arg1 = st->top();
Literal* arg2 = st->top();
Literal* result = applyOperator(arg1, arg2);
st->pop(); st->pop();
st->push(result);
}
Literal* execute(IntegerLiteral* a, IntegerLiteral* b) {
return new IntegerLiteral(a->getValue() + b->getValue());
}
Literal* execute(IntegerLiteral* a, RealLiteral* b) {
return new RealLiteral(a->getValue() + b->getValue());
}
Literal* execute(IntegerLiteral* a, RationalLiteral* b) {
return new RationalLiteral(
a->getValue() + (a->getValue()*b->getDenominator()),
b->getDenominator()
);
}
// ...
};
My purpose here (by overloading the function applyOperator) is to "magically" let the computer know which function call depending on the real type of Literal unstacked by the operator (the class Literal is abstract : the stack will always contain specifics Literal's subclasses).
But it does not work the way I want.
I mean that the call applyOperator(arg1, arg2) (with arg1 and arg2 being Literal*) is invalid because no functions match the signature.
I'm aware that I kind of use the c++ polymorphism int the other way that it's normally used (that is give a subclass argument to a function that take a superclass argument).
I don't know how to turn around my architecture in order to properly use the polymorphism et maybe there is some syntax helpful solution in order to make my idea work.
Either way, I'm grateful for your help !!
Raphael.
There is a way to do it with polymorphism as intended (without dynamic_cast):
#include <iostream>
#include <memory>
#include <string>
struct IntegerLiteral;
struct RealLiteral;
struct Literal {
virtual void add(const Literal &) = 0;
virtual void add(const IntegerLiteral &) = 0;
virtual void add(const RealLiteral &) = 0;
virtual void add_to(Literal &) const = 0;
virtual void add_to(IntegerLiteral &) const = 0;
virtual void add_to(RealLiteral &) const = 0;
virtual std::ostream &print(std::ostream &os) const = 0;
virtual ~Literal() = default;
};
std::ostream &operator<<(std::ostream &os, const Literal &l) {
return l.print(os);
}
struct IntegerLiteral : Literal {
IntegerLiteral(int i)
: i(i) {}
int i = 0;
void add(const Literal &other) override {
//now we know one operand is an IntegerLiteral and can pass on that information to the other Literal
other.add_to(*this);
}
void add(const IntegerLiteral &other) override {
i += other.i;
}
void add(const RealLiteral &other) override;
void add_to(Literal &other) const override {
other.add(*this);
}
void add_to(IntegerLiteral &other) const override {
other.i += i;
}
void add_to(RealLiteral &other) const override;
std::ostream &print(std::ostream &os) const override {
return os << i;
}
};
struct RealLiteral : Literal {
RealLiteral(double d)
: d(d) {}
double d = 0;
void add(const Literal &other) override {
other.add_to(*this);
}
void add(const IntegerLiteral &other) override {
d += other.i;
}
void add(const RealLiteral &other) override {
d += other.d;
}
void add_to(Literal &other) const override {
other.add(*this);
}
void add_to(IntegerLiteral &other) const override {
//now we know both operands and can do the calculation
other.i += d;
}
void add_to(RealLiteral &other) const override {
other.d += d;
}
std::ostream &print(std::ostream &os) const override {
return os << d;
}
};
void IntegerLiteral::add(const RealLiteral &other) {
i += other.d;
}
void IntegerLiteral::add_to(RealLiteral &other) const {
other.d += i;
}
int main() {
std::unique_ptr<Literal> l1 = std::make_unique<RealLiteral>(3.14);
std::unique_ptr<Literal> l2 = std::make_unique<IntegerLiteral>(42);
l1->add(*l2);
std::cout << *l1 << '\n';
}
DEMO
You need a ton of code to make this work and it gets quadratically worse with every Literal you add and twice as bad with every operator. Also if you forget to override a function you are likely to get an infinite loop and a stack overflow at run time.
A much better approach (easier to write and faster to run) would be to just use double or BigNum for everything and not bother with polymorphism.
You are mixing different concepts, which are ad hoc polymorphism (overloads) and subtype polymorphism, which in is implemented through late binding of methods through virtual tables.
Basically what happens is that the compiler chooses which overloaded method to call at compile time, not at runtime. This makes impossible what you are trying to do without using RTTI.
The compiler is not able to determine which will be the type of the two Literal instances, and C++ supports only early binding when dealing with non virtual methods. The only thing that it can deduce at compile time is the fact that both arguments are of type Literal* so it looks for that overload only.
You need a sort of dynamic switch to do what you want, which can be obtained through the use of dynamic_cast (or similar hand made solutions).

C++ What operators I need to overload to make this A1 += A2 * floatValue work?

What operators I need to overload to make this word?
Variables A1 and A2 both of type class A, variable floatValue is of type float.
A1 += A2 * floatValue;
I have overloaded this operators
A operator+() const;
A operator+=(const A value);
A operator*(const A value);
friend A operator*(const A val2, float val);
But, I receive error "Class A has no suitable copy constructor"
I have this constructors in my class
A();
A(float val1, float val2);
A(float value);
Thanks for answering.
Minimal example:
#include <iostream>
using namespace std;
struct foo {
float val;
foo(float val): val(val){}
foo &operator+=(foo const &other) {
this->val += other.val;
return *this;
}
friend foo operator*(foo const &lhs, foo const &rhs) {
return lhs.val*rhs.val;
}
};
int main() {
foo a = 5, b = 6;
a += b * 3;
cout << a.val << endl;
return 0;
}
see: http://ideone.com/6pD2pr
With an explicit constructor you might want to use this example instead:
#include <iostream>
using namespace std;
struct foo {
float val;
explicit foo(float val): val(val){}
foo &operator+=(foo const &other) {
this->val += other.val;
return *this;
}
friend foo operator*(foo const &lhs, float val) {
return foo(lhs.val*val);
}
};
int main() {
foo a(5), b(6);
a += b * 3;
cout << a.val << endl;
return 0;
}
see: http://ideone.com/o8Vu1d
Whenever you overload an assignment operator like
A operator+=(const A value);
you also need to define a copy constructor like
A( const A& );
The copy constructor will be used by the assignment operator.
This is part of what's known as the Rule of Three.
When you have function like this:
fun(A a);
Arguments here are passed by value, so you need to have copy constructor for A (in order to create new instance from another instance), OR you can change it to reference, so no copy constructor will be needed.
Like this:
A operator+=(const A &value);

Overloading operator []

Let's say I have a container class called MyContainerClass that holds integers.
The [] operator, as you know, can be overloaded so the user can more intuitively access values as if the container were a regular array. For example:
MyContainerClass MyInstance;
// ...
int ValueAtIndex = MyInstance[3]; // Gets the value at the index of 3.
The obvious return type for operator[] would be int, but then the user wouldn't be able to do something like this:
MyContainerClass MyInstance;
MyInstance[3] = 5;
So, what should the return type for operator[] be?
The obvious return type is int& :)
For increased elaboration:
int &operator[](ptrdiff_t i) { return myarray[i]; }
int const& operator[](ptrdiff_t i) const { return myarray[i]; }
// ^ could be "int" too. Doesn't matter for a simple type as "int".
This should be a reference:
int &
class MyContainerClass {
public:
int& operator[](unsigned int index);
int operator[](unsigned int index) const;
// ...
};
Returning a reference lets the user use the result as an lvalue, as in your example MyInstance[3] = 5;. Adding a const overload makes sure they can't do that if MyInstance is a const variable or reference.
But sometimes you want things to look like that but don't really have an int you can take a reference to. Or maybe you want to allow multiple types on the right-hand side of MyInstance[3] = expr;. In this case, you can use a dummy object which overloads assignment:
class MyContainerClass {
private:
class Index {
public:
Index& operator=(int val);
Index& operator=(const string& val);
private:
Index(MyContainerClass& cont, unsigned int ind);
MyContainerClass& m_cont;
unsigned int m_ind;
friend class MyContainerClass;
};
public:
Index operator[](unsigned int ind) { return Index(*this, ind); }
int operator[](unsigned int ind) const;
// ...
};
int&
returning a reference allows you too use the returned value as a left-hand side of the assignment.
same reason why operator<<() returns an ostream&, which allows you to write cout << a << b;