1

I am trying to define my operator overloading outside the class like this:

template <typename Type>
class myClass
{
    ...
    friend std::ostream& operator << (std::ostream&, const myClass&);
    friend std::istream& operator >> (std::istream&, myClass&);
    ...
}

template <typename Type>
std::ostream& myClass<Type> :: operator << (std::ostream& out, const myClass<Type>& other) { ... }

template <typename Type>
std::istream& myClass<Type> :: operator >> (std::istream& in, myClass<Type>& other) { ... }

My problem is that I get an error saying something like "class template class has no member operator<<" and I do not understand how or why is this happening.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Member function != namespace scope function. The `friend` declarations in `myClass` are for global functions, but you're trying to implement them as member functions. Try dropping the `myClass ::` in the implementation. – Brian61354270 Dec 12 '21 at 21:02
  • Also, you're missing a `;` after the class declaration, but I assume that's just a copy-paste error. – Brian61354270 Dec 12 '21 at 21:07
  • If I drop the myClass from the declaration it gives me a linker error and yes, copy paste error, forgot a ; after class declaration – EpicShadowXD Dec 12 '21 at 21:07

1 Answers1

3

For starters the friend functions are not member functions of the class where they are declared.

So these declarations in any case are incorrect.

template <typename Type>
std::ostream& myClass<Type> :: operator << (std::ostream& out, const myClass<Type>& other) { ... }

template <typename Type>
std::istream& myClass<Type> :: operator >> (std::istream& in, myClass<Type>& other) { ... } 

Secondly within the class definition you declared non-template friend functions.

Either you need to provide their definitions within the class definition. Or for each potential template argument of the class you have to define the friend functions outside the class.

Here is a demonstration program that shows how to define a non-template friend function within the class template definition.

#include <iostream>

template <typename T>
class A
{
private:
    T t;

public:
    A( const T &t ) : t( t ) {}

    friend std::ostream &operator <<( std::ostream &os, const A &a )
    {
        return os << a.t;
    }
};


int main()
{
    std::cout << A<int>( 10 ) << '\n';
    std::cout << A<const char *>( "Hello" ) << '\n';
}

The program output is

10
Hello

And here is a demonstration program that shows how to define the friend functions outside the class template definition. That is for each used specialization of the class template you need to define the non-template friend functions.

#include <iostream>

template <typename T>
class A
{
private:
    T t;

public:
    A( const T &t ) : t( t ) {}

    friend std::ostream &operator <<( std::ostream &os, const A &a );
};


std::ostream &operator <<( std::ostream &os, const A<int> &a )
{
    return os << a.t;
}

std::ostream &operator <<( std::ostream &os, const A<const char *> &a )
{
    return os << a.t;
}

int main()
{
    std::cout << A<int>( 10 ) << '\n';
    std::cout << A<const char *>( "Hello" ) << '\n';
}

An alternative approach is to declare template friend functions. For example

#include <iostream>

template <typename T>
class A
{
private:
    T t;

public:
    A( const T &t ) : t( t ) {}

    template <typename T>
    friend std::ostream &operator <<( std::ostream &os, const A<T> &a );
};

template <typename T>
std::ostream &operator <<( std::ostream &os, const A<T> &a )
{
    return os << a.t;
}

int main()
{
    std::cout << A<int>( 10 ) << '\n';
    std::cout << A<const char *>( "Hello" ) << '\n';
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I want define them outside the class but I can't seem to make it work. – EpicShadowXD Dec 12 '21 at 21:13
  • 1
    @EpicShadowXD Defining a templated friend function outside of the class has a few subtleties to it. Defining it inline usually results in more readable code. See [overloading friend operator<< for template class](https://stackoverflow.com/q/4660123/11082165) – Brian61354270 Dec 12 '21 at 21:14
  • @EpicShadowXD See my appended answer. – Vlad from Moscow Dec 12 '21 at 21:18
  • Vlad, please, I beg you, I want to make it OUTSIDE. I've been crying here for the last week cuz I can't make it work outside the class template. I've made it work inside but I want to do it outside to separate definition and declaration into 2 separate files. – EpicShadowXD Dec 12 '21 at 21:18
  • @Brian I did it literally how David Rodriguez says there and I get a linker error :((((((((((((((((((((((((((( – EpicShadowXD Dec 12 '21 at 21:25
  • May God give you happiness but I kind of need to use templates for versatility in my case. Do you know if I have a workaround manually overwriting for every type imaginable? – EpicShadowXD Dec 12 '21 at 21:32
  • @EpicShadowXD If specializations of the class differ then you need to specialize also the friend functions. Or as I showed a non-template friend function can be defined within the class definition. – Vlad from Moscow Dec 12 '21 at 21:33
  • Thank you, Vlad. I finally understood thanks to you. May God give you eternal bliss for helping me with this week long hemorroid. – EpicShadowXD Dec 12 '21 at 21:38