StackIT
StackIT

Reputation: 1200

C++ Templates and operator overloading

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

Answers (3)

luk32
luk32

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

Potatoswatter
Potatoswatter

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

Stefano Falasca
Stefano Falasca

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:

  1. i is converted to an int
  2. f is converted to a float
  3. the operation (+) is performed
  4. T tempType<int>::operator=(T val) is called for the assignement

Upvotes: 1

Related Questions