0

After countless hours of google searching for answer, I wasn't able to find out how to override input operator for template class in c++. I have found answers for how to override operator for regular classes and how to override output operator. Trying to combine what I learnt from those led to nothing.

The code I wrote so far is:

Header file for class:

#include <iostream>
template <class T>
class Set
{
private:
    T **array;
    int max;

public:
    Set();
    Set(int);
    ~Set();
    int Max()
    {
        return max;
    };
    friend std::ifstream& operator>> (std::ifstream &input, Set<T> &obj)
    {
        for (int i = 0; i < obj->max; i++)
        {
            T a;
            input >> a;
            obj.array[i] = new T;
            obj.array[i] = a;
        }
        return input;
    };
};

template <class T>
Set<T>::Set()
{
    max = 0;
    array = new T *[max];
}

template <class T>
Set<T>::Set(int a)
{
    max = a;
    array = new T *[max];
}
template <class T>
Set<T>::~Set()
{
    delete[] array;
}

Main program:

#include "set.hpp"

int main(){
    Set<float> obj;
    std::cin >> obj;
    return 0;
}

When trying to compile I get the following two errors:

no match for 'operator>>' (operand types are 'std::istream' {aka 'std::basic_istream<char>'} and 'Set<float>')
no operator ">>" matches these operands -- operand types are: std::istream >> Set<float>

If it is important I am using gcc compiler. Thank you!

  • `obj.array[i] = new T; obj.array[i] = a;` doesn't compile. should be `*obj.array[i] = a;`. – Jarod42 Jan 16 '21 at 18:10
  • Another "typos": `std::ifstream` != `std::istream` (no `f`). `std::cin` isn't the former, but is the later. – Jarod42 Jan 16 '21 at 18:12
  • your destructor forget to delete element of the array. using `std::vector` as member might solve lot of issue. – Jarod42 Jan 16 '21 at 18:14
  • Top result on my first google search [overload operator in template class](https://stackoverflow.com/questions/4014294/operator-overloading-on-class-templates) and it shows code example on how you do it. I'm feeling like your not being completely honest about your countless hours of searching. – super Jan 16 '21 at 18:17
  • Thank you guys, we were asked for this problem to use arrays, not vectors. I will fix the typos, for some reason I keep writing ifstream instead of istream... Both my friend and me stumbled upon the linked question but we were not able to fully implement/understand proposed solutions. I did move the operator function to header file as it was suggested in that exact question though. I will research a bit more into the templates and hopefully I would acquire required knowledge. Thank you again! – Luka Lazarević Jan 16 '21 at 19:54

1 Answers1

-1

You can overload like this:

template <class T>
class Set
{
...
    template<typename U>
    friend std::istream& operator>> (std::istream &input, Set<U> &obj);
};

template<typename T>
std::istream& operator>> (std::istream &input, Set<T> &obj)
{
   ...
    return input;
}

OR

you can define it in class like:

template <class T>
class Set
{
...
    friend std::istream& operator>> (std::istream &input, Set<T> &obj)
    {
        return input
    }
}

In the first one you are declaring my friend operator >> instantiations a friend of one instantiation of set<> template class. In the second we have inlined the friend function to allow only one instantiation of friend operator >> to be friend of one instantiation of set<>

Here is a better answer SO, that is related to operator <<. I can delete my answer if OP can get a better idea with the linked one.

The Philomath
  • 954
  • 9
  • 15
  • I prefer OP's version (with typos fixed), function is not template (that allows to match derived class if any, and build in place). only friend for correct function (your `operator >> ` has access to `set`). – Jarod42 Jan 16 '21 at 18:19