-2

I am trying to overload ostream and istream as a freind of the class in a template. I have looked online but have not been able to find much that specifies about template overloading, also what I have seen seems to state that this is the prpoer way to orevload these. It is obvious that I am very new to programming and would appreciate any help. Thank you.

#include <stdio.h>
#include<vector>
#include<iostream>
using namespace std;
template<class T>
class MyClass

{
enter code here
public:
    MyClass();
    MyClass(const T& p_val1);
    MyClass(const MyClass<T>& p_val1);
    ~MyClass();
    MyClass<T>& operator=(MyClass<T>& rhs);

    friend ostream& operator<<(ostream& lhs, const MyClass<T> &printme);
    friend istream& operator>><T>(istream& lhs, MyClass<T>& readme);

private:
    T* m_val1;

};

implementation of the ostream and istream.

template<class T>
ostream& operator<<(ostream&lhs, const MyClass<T>& printme)
{
    lhs << printme.m_val1;
    return lhs;
}
template<class T>
istream& operator>>(istream& lhs, MyClass<T>& readme)
{
    lhs >> *(readme.m_val1);
    return lhs;
}

here are the errors

Undefined symbols for architecture x86_64:
  "MyClass<int>::~MyClass()", referenced from:
      _main in main.o
  "operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, MyClass<int> const&)", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Main function

  MyClass<int> a(8);
    MyClass<int> b(9);
    cout << " Enter a value for the two types to be swapped: ";
    cin >> a >> b;
    cout << "Before swapping...\n";
    cout << "Object a's pointer member dereferences a value of:\t" << a << endl;
    cout << "Object b's pointer member dereferences a value of:\t" << b << endl;
G.Erezuma
  • 1
  • 1

1 Answers1

0

You are declaring your operators, but not defining them. The template definition isn't related to the ones inside your class, as their prototype is different, hence the link error. Change your declaration to this:

template <typename T, typename Trait>
friend std::basic_ostream<T, Trait>&
operator<< (std::basic_ostream<T, Trait>& out, const MyClass& c)
{
    return out << c.my_val1;
}

template <typename T, typename Trait>
friend std::basic_istream<T, Trait>&
operator>> (std::basic_istream<T, Trait>& in, MyClass& c)
{
    return in >> *(c.my_val1);
}

Note that it's using std::basic_ostream and std::basic_istream, with their respective type and type trait. It allows for all streams to be used, not only std::ostream and std::istream.

Mário Feroldi
  • 2,935
  • 2
  • 21
  • 42