Reputation: 441
#ifndef NUMBER_HPP
#define NUMBER_HPP
template <class T>
class Number
{
public:
Number( T value ) : m_value( value )
{
}
T value() const
{
return m_value;
}
void setValue( T value )
{
m_value = value;
}
Number<T>& operator=( T value )
{
m_value = value;
}
// template <class T2>
// Number<T2>& operator=( const Number<T>& number )
// {
// m_value = number.value();
// return *this;
// }
private:
T m_value;
};
typedef Number<int> Integer;
typedef Number<float> Float;
typedef Number<double> Double;
#endif // NUMBER_HPP
The commented assignment operator overloading is my attempt to do what I want, I thought it might provide a better description than the one above the snippet.
I want to be able to do the following:
Float a(10);
Integer b(20);
a = b;
Where a
then would be casted to an int
and given the value of b
, but still be an instance of class Number
.
Is it possible? Can you help me out here?
Thanks in advance.
Upvotes: 9
Views: 24884
Reputation: 405
In case you want more of a built-in feel, the value() and setValue() can be replaced with assignment and cast:
#include <iostream>
template <class T>
class Number
{
public:
Number() : m_value( 0 ) { }
Number( T value ) : m_value( value ) { }
Number<T>& operator=( T value )
{
m_value = value;
return *this;
}
template <class T2>
Number<T>& operator=( const Number<T2>& in )
{
m_value = static_cast< T >( in );
return *this;
}
operator int() const
{
return m_value;
}
operator float() const
{
return m_value;
}
friend std::ostream& operator<<( std::ostream& s, Number<T>& in )
{
s << static_cast< T >( in );
return s;
}
private:
T m_value;
};
typedef Number<int> Integer;
typedef Number<float> Float;
typedef Number<double> Double;
int main()
{
Integer a[5] = { 0, 1, 2, 3, 4 };
Double b(3);
a[0] = 1;
b = 2;
b = a[0];
std::cout << "b is " << b << std::endl;
std::cout << "a[3] is " << a[3] << std::endl;
return 0;
}
Upvotes: 0
Reputation: 361692
You should do this:
template <class T2>
Number<T>& operator=( const Number<T2>& number )
{
m_value = number.value();
return *this;
}
That is, use T2
in the parameter type, not in the return type!
I would rather use different letter for template parameter:
template <class U>
Number<T>& operator=( const Number<U>& number )
{
m_value = number.m_value; //I would also directly access the member variable!
return *this;
}
I think, it is better to use explicit cast, if you want to use class type as template argument and whose constructor has been declared explicit
:
m_value = static_cast<T>(number.m_value);
By the way, the other operator=
should be implemented as:
Number<T>& operator=(T const & value ) //accept by const reference
{
m_value = value;
return *this; //you've to return!
}
Upvotes: 11
Reputation: 75150
You have some of the T
s in the wrong place. It should be
template <class T2>
Number<T>& operator=( const Number<T2>& number )
{
m_value = number.value();
return *this;
}
This will let you do
Integer a(4);
Float b(6.2f);
a = b;
cout << a.value() << endl;
and it will print 6
, a behaviour similar to that of the int
and float
types you are imitating.
Upvotes: 5