Sourav Kanta
Sourav Kanta

Reputation: 2757

Template Argument in Template-Class Assignment Operator

I am trying to write a generic class MyStack to implement a Stack. I have a template variable inside my class by the typename of Data. I am also overloading the = operator to copy an existing MyStack object to another existing MyStack object. I therefore want to check if two class objects have the same type of variable before copying i.e, I don't want an object of type float to be copied to an object of type int. What would be a good way to achieve this task ?

MyStack Definition :

template<typename Data>
class MyStack
{
    Data *data;
    int pos;
    int Max;
    MyStack();

    public:

    MyStack(int);
    int push(const Data);
    int push(const Data *,const Data);
    Data pop();
    Data* pop(const int);
    int getMaxSize();
    int currSize();
    int isEmpty();
    void display();
    MyStack(const MyStack &);
    void operator=(const MyStack s);
    ~MyStack();
};

And here's the operator overloading part :

template<typename Data>
void MyStack<Data>::operator=(const MyStack s)
{
    cout<<"Copied with operator overloading"<<endl;
    delete[] data;
    data=new Data[s.Max];
    Max=s.Max;
    pos=s.pos;
    for(int i=0;i<=s.pos;i++)
            data[i]=s.data[i];
}

Thanks in advance.

Upvotes: 1

Views: 3143

Answers (1)

Ami Tavory
Ami Tavory

Reputation: 76406

In the declaration

void operator=(const MyStack s);

You have a number of problems (see overloading special members):

  1. The return type should be MyStack<Data> &.
  2. s should be a const reference.
  3. The type to which s should be a const reference to, is MyStack<Data> as well.

Note that MyStack is not an actual type. It is a "type factory".

Overall, then, it should look like

MyStack<Data> &operator=(const MyStack<Data> &s);

This will incidentally solve your question - it will only take const references to MyStack templates instantiated to the same Data.


If you would like to support assignments from other stack types as well, you might consider something like the following:

#include <type_traits>

template<typename Data>
class MyStack
{
...

    template<typename OtherData>
    typename std::enable_if<
        std::is_convertible<OtherData, Data>::value,
        MyStack<Data> &>::type
        operator=(const MyStack<OtherData> &other);
};

This uses:

Upvotes: 1

Related Questions