Reputation: 1200
I am learning templates and operator overloading. I have written some code but I am confused... Let me explain...
template <class T>
class tempType
{
public:
T value;
bool locked;
tempType():locked(false)
{
value = 0;
}
T operator=(T val)
{
value=val;
return value;
}
tempType<T> operator=(tempType<T> &val)
{
value=val.value;
return *this;
}
operator T()
{
return value;
}
};
And I did...
int main(void)
{
tempType<int> i;
tempType<bool> b;
tempType<float> f;
i.value = 10;
i = i + f;
return 0;
}
What code I need to write in order to execute
tempType<T> operator=(tempType<T> &val){}
Also, I why operator T()
is required?
Upvotes: 0
Views: 162
Reputation: 16090
I think I know all the answers so I might as well post full response.
To override default operator=
you should declare it as tempType<T> operator=(const tempType<T> &val){}
. Now you need to call the method explicitly via i.operator=(other_i).
If you correct the declaration you can use it like this:
tempType<int> i;
tempType<int> other_i;
i = other_i; // this is what you just defined
The operator T()
is called a conversion operator. It is kind of reverse or counter part of the conversion constructor which in your case would be tempType(const &T value)
.
It is used to convert a class object into a given type. So in your case you would be able to write:
tempType<int> i;
int some_int;
some_int = i; // tempType<int> gets converted into int via `operator int()`
Upvotes: 2
Reputation: 137940
Unless you implement move semantics, operator=
should always take a const &
reference to the source value. It should also return a reference to the modified object.
tempType & operator=(T const & val)
{
value=val;
return * this;
}
operator T
is an implicit conversion function which allows any tempType
object to be treated as an object of its underlying type T
. Be careful when specifying implicit conversions that they won't conflict with each other.
An implicit conversion function usually shouldn't make a copy, so you probably want
operator T & ()
{
return value;
}
operator T const & () const
{
return value;
}
Given these, you shouldn't need another overload of operator =
because the first overload will simply be adapted by the conversion function to a call such as i = b;
.
If a series of conversions will result in the operator=(T const & val)
being called, you should avoid also defining operator=(tempType const & val)
because the overloads will compete on the basis of which conversion sequence is "better," which can result in a brittle (finicky) interface that may refuse to do seemingly reasonable things.
Upvotes: 2
Reputation: 9097
template <class T>
class tempType
{
public:
T value;
bool locked;
tempType() : value(), locked(false)
{
value = 0;
}
//althought legal, returning something different from tempType&
//from an operator= is bad practice
T operator=(T val)
{
value=val;
return value;
}
tempType& operator=(const tempType &val)
{
value=val.value;
return *this;
}
operator T()
{
return value;
}
};
int main(void)
{
tempType<int> a;
tempType<int> b;
a = b;
return 0;
}
in the code, a = b
calls the operator.
As for the second question, the operator T()
is not needed "by default". In your example, it is used when you write i+f
:
i
is converted to an intf
is converted to a floatT tempType<int>::operator=(T val)
is called for the assignementUpvotes: 1