-1

I am a beginner in C++.I am trying to overload my cout operator for my template. However, it does not accept the way that i used for my classes' operators.So, i am here to learn your thoughts.

This is my header

#include <iostream>
using namespace std;
template <class T>
class Set{

    private:
        T *data;
        int index;
    public:
        Set() :index(0){
            data=new T[100];
        }

        void addElement(T t){
            int x=0,i;
            for(i=0;i<index;i++){           // to add element
                if(data[i]==t){
                    cout<<"This element ("<<t<<") cannot be added since it is already in the elements"<<endl;
                    x=1;
                }
            }
            if(x!=1)data[index++]=t;
        }                   
        ostream& operator<<(ostream& s,const Set<T1>& b){ //place in which i want to overload

            s<<"Printed";
            return s;
        }


};

This is my main

#include <iostream>
#include<string.h>
using namespace std;

#include "Stack.h"

int main(){
    Set<int> x1;
    x1.addElement(4);
    x1.addElement(7);
    cout<<x1;





    return 0;
    }

1 Answers1

0

Your problem has nothing to do with your class being templated.

You are trying to implement your operator<< as a non-static member of your class, but that won't work for the binary stream operator<<, it needs to be a non-member instead. A binary operator implemented as a class member can only be a member of the class in its left-hand argument, which in this case is std::ostream, and your class is not the std::ostream class. As such, the operator needs to be a free function (non-member) instead.

If you mark the binary operator<< as a friend inside the class, not only will it have access to the private members of your class, but more importantly the compiler will treat the operator as a free function in the surrounding namespace that your class is declared in, which is what you need, eg:

template <class T>
class Set{

    ...

    public:
        ...

        // inlined implementation
        friend ostream& operator<<(ostream& s, const Set& b){
            ...
            return s;
        }
};

Or:

template <class T>
class Set{
    ...
    // non-inlined implementation
    friend ostream& operator<<(ostream& s, const Set& b);
};

template <class T>
ostream& operator<<(ostream& s, const Set<T>& b){
    ...
    return s;
}

On a side note, your addElement() has a potential buffer overflow. It should look more like this instead:

void addElement(const T& t){
    for(int i = 0; i < index; ++i){
        if (data[i] == t){
            cout << "This element (" << t << ") cannot be added since it is already in the elements" << endl;
            return;
        }
    }
    if (index >= 100){
        cout << "This element (" << t << ") cannot be added since the elements is full" << endl;
        return;
    }
    data[index++] = t;
}

Also, your class is missing:

  • a destructor, to delete[] the elements array.
  • a copy constructor and copy-assignment operator, to make deep copies of the elements data between Set objects.
  • (C++11 and later) a move constructor and move-assignment operator, to move the array between objects.

Per the Rule of 3/5/0.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you ,but i got error " undefined reference to operator < const&)" – Mert Özçelik May 14 '20 at 23:47
  • @MertÖzçelik You would have to edit your question to show your updated code, but I'm guessing that you either defined the operator incorrectly, or you put it in the wrong place. See [What is the proper way to overload an operator for a class?](https://stackoverflow.com/questions/2828280/) and [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/). – Remy Lebeau May 14 '20 at 23:53