problem with my Number<T> class
Apr 10, 2015 at 8:35am UTC
Hi, i just made my
Number<T>
class and I'm having problems doing operations with different types of
Number
s
For example
1 2 3 4
Number<double > x = 2.4;
Number<int > y = 2;
cout << x * y << endl; // works great
cout << Y * x << endl; // wrong results, truncates 4.8 to 4
This is why its happening
I'm returning type of the 1st operand and in 2nd case 1st is <int>
Is there a way i could make this work like its supposed to?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
template <class T, class U>
Number<T> operator *(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() * n2.get());
}
template <class T, class U>
Number<T> operator /(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() / n2.get());
}
template <class T, class U>
Number<T> operator +(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() + n2.get());
}
template <class T, class U>
Number<T> operator -(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() - n2.get());
}
Here is all code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
#include <vector>
#include <iostream>
using namespace std;
template <class T>
class Number{
public :
Number(T);
Number() : val(T(0)){}
Number(const Number& n);
Number& operator =(const Number&);
Number operator +(const Number&) const ;
Number operator -(const Number&) const ;
Number operator *(const Number&) const ;
Number operator /(const Number&) const ;
Number operator %(const Number&) const ;
Number operator +(const T&) const ;
Number operator -(const T&) const ;
Number operator *(const T&) const ;
Number operator /(const T&) const ;
operator double () { return val; }
operator int () { return val; }
Number& operator ++();
Number& operator --();
T get() const { return val; }
void set(T t){ val = t; }
private :
T val;
};
template <class T>
Number<T>::Number(T t = T(0)) : val(t){}
template <class T>
Number<T>::Number(const Number& n) : val(n.get()){}
template <class T>
Number<T>& Number<T>::operator =(const Number& n){
val = n.get();
return *this ;
}
template <class T>
Number<T> Number<T>::operator +(const Number<T>& v)const {
return Number<T>(val + v.get());
}
template <class T>
Number<T> Number<T>::operator -(const Number<T>& v)const {
return Number<T>(val - v.get());
}
template <class T>
Number<T> Number<T>::operator *(const Number<T>& v)const {
return Number<T>(val * v.get());
}
template <class T>
Number<T> Number<T>::operator /(const Number<T>& v)const {
Number<T> t(val / v.get());
return t;
}
template <class T>
Number<T> Number<T>::operator %(const Number<T>& n)const {
return Number<T>(val % n.get());
}
template <class T, class U>
Number<T> operator *(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() * n2.get());
}
template <class T, class U>
Number<T> operator /(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() / n2.get());
}
template <class T, class U>
Number<T> operator +(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() + n2.get());
}
template <class T, class U>
Number<T> operator -(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() - n2.get());
}
template <class T>
Number<T> Number<T>::operator +(const T& v)const {
return Number<T>(val + v);
}
template <class T>
Number<T> Number<T>::operator -(const T& v)const {
return Number<T>(val - v);
}
template <class T>
Number<T> Number<T>::operator *(const T& v)const {
return Number<T>(val * v);
}
template <class T>
Number<T> Number<T>::operator /(const T& v)const {
Number<T> t(val / v);
return t;
}
template <class T>
Number<T>& Number<T>::operator ++(){
val++;
return *this ;
}
template <class T>
Number<T>& Number<T>::operator --(){
val--;
return *this ;
}
template <class T>
ostream& operator <<(ostream& os, const Number<T>& n){
os << n.get();
return os;
}
template <class T>
istream& operator >>(istream& is, Number<T>& n){
T x;
is >> x;
if (!is){
is.clear(ios_base::failbit);
return is;
}
n.set(x);
return is;
}
int main(){
Number<double > x = 2.49;
Number<int > y = 2;
cout << y * x << endl;
}
EDIT : On cpp.sh its not even compiling, but it did on my visual studio 2013
Side question - why is cpp.sh giving me compiler error
39:29: error: redeclaration of 'Number<T>::Number(T)' may not have default arguments [-fpermissive]
But if if write definition
Number(T t = T(0)) : val(t){}
inside my class and remove
1 2
template <class T>
Number<T>::Number(T t = T(0)) : val(t){}
it suddenly compiles. Whats going on here?
Last edited on Apr 10, 2015 at 9:01am UTC
Apr 10, 2015 at 10:25am UTC
it suddenly compiles. Whats going on here?
Default parameters are only allowed for the declaration and not the definition of a function.
Is there a way i could make this work like its supposed to?
The problem appears because of line 27: an implicite cast to int. Therefore the operator on line 23 is chosen by the compiler.
I'd say remove line 26/27.
Apr 10, 2015 at 12:42pm UTC
Tnx a lot for reply man.
But if i remove line 27 i wont be able to do stuff like this
1 2 3
int x;
Number<int > y = 40;
x = y;
EDIT : just checked out and removed line 27
Still its not working. I think the problem is here
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
template <class T, class U>
Number<T> operator *(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() * n2.get());
}
template <class T, class U>
Number<T> operator /(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() / n2.get());
}
template <class T, class U>
Number<T> operator +(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() + n2.get());
}
template <class T, class U>
Number<T> operator -(const Number<T>& n1, const Number<U>& n2){
return Number<T>(n1.get() - n2.get());
}
If left operand is
Number<int >
operator will return
Number<int >
and it truncates my result
to
On the other hand if left operand is
Number<double >
the return type will be
Number<double >
and im getting the right result
How could i return
Number<Int>
if both operands are
Number<int >
and
Number<double >
if one of them is
Number<double >
Last edited on Apr 10, 2015 at 12:49pm UTC
Apr 10, 2015 at 1:00pm UTC
The problem appears because of line 27: an implicite cast to int. Therefore the operator on line 23 is chosen by the compiler.
You are right but this doesn't make any sence to me
Apr 10, 2015 at 1:33pm UTC
Try using operator T(){ return val; }
instead?
Apr 10, 2015 at 1:40pm UTC
Thank you man, this looks cool however with my new code where i removed all the
1 2 3 4 5 6 7 8 9 10 11 12
template <class T>
Number<T> Number<T>::operator +(const T& v)const {
return Number<T>(val + v);
}
template <class T>
Number<T> Number<T>::operator -(const T& v)const {
return Number<T>(val - v);
}
template <class T>
Number<T> Number<T>::operator *(const T& v)const {
return Number<T>(val * v);
}
because with
operator T(){ return val; }
i feel like i don't need them anymore I started to have 1 linker error
Error 1 error LNK2019: unresolved external symbol "public: class Number<int> & __thiscall Number<int>::operator=(class Number<int> const &)" (??4?$Number@H@@QAEAAV0@ABV0@@Z) referenced in function "void __cdecl std::swap<class Number<int> >(class Number<int> &,class Number<int> &)" (??$swap@V?$Number@H@@@std@@YAXAAV?$Number@H@@0@Z)
Error 2 error LNK1120: 1 unresolved externals
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#include <vector>
#include <iostream>
using namespace std;
template <class T>
class Number{
public :
Number(T);
Number() : val(T(0)){}
Number(const Number& n);
Number& operator =(const Number&);
operator T() const { return val; }
Number& operator ++();
Number& operator --();
T get() const { return val; }
void set(T t){ val = t; }
private :
T val;
};
template <class T>
Number<T>::Number(T t) : val(t){}
template <class T>
Number<T>::Number(const Number& n) : val(n.get()){}
template <class T>
Number<T>& Number<T>::operator ++() {
val++;
return *this ;
}
template <class T>
Number<T>& Number<T>::operator --(){
val--;
return *this ;
}
template <class T>
ostream& operator <<(ostream& os, const Number<T>& n){
os << n.get();
return os;
}
template <class T>
istream& operator >>(istream& is, Number<T>& n){
T x;
is >> x;
if (!is){
is.clear(ios_base::failbit);
return is;
}
n.set(x);
return is;
}
int main(){
Number<double > y2{2.5}; // works great
cout << "y2 = " << y2 << endl;
const Number<double > x = 2.49; // all good
const Number<int > y = 2 // very good
//y++;
Number<double > x2 = x*y; // excellent
cout << x2 << endl; // bellisimo
vector<Number<int >> vec{ 2}; // linker error =[
system("pause" );
}
Whats going on now? As i see it element 0 in vector should be initialized to 2 but instead I'm getting error
Even
vector<Number<int >> vec{ Number < int > {3} };
gives error
Last edited on Apr 10, 2015 at 2:53pm UTC
Apr 10, 2015 at 3:15pm UTC
The function on line 11 is never defined in your code. Either define it yourself, or default it so the compiler defines it for you:
Number& operator =(const Number&) = default ;
Apr 10, 2015 at 3:22pm UTC
Thank you very much man, this topic can be safely closed now :)
Apr 10, 2015 at 3:27pm UTC
Topics can't be closed. Marking it as solved is sufficient ;)
Topic archived. No new replies allowed.