0

I want to overload the << operator in my template class, and define it outside the template class.

using namespace std;

template <class T> class Child {

    public:
        
    friend ostream &operator << (ostream &Output, const Child &Object);

};

// What can I change to make my code work?
ostream &operator << (ostream &Output, const Child <T> &Object) {

}

As you can see, I don't know what the correct syntax is so that my code can run without errors. My C++ book does not go this in-depth. This has been really frustrating me so I would appreciate any help. Thank you :)

Anatoly
  • 20,799
  • 3
  • 28
  • 42
  • 1
    I think you need to [read this answer](https://stackoverflow.com/a/4661372/1322972). From that answer, I'd suggest you study them all, but ultimately consider option(3). – WhozCraig Nov 29 '20 at 04:44

3 Answers3

2

It needs to be a function template if you're going to have it accept a templated type (const Child<T> &Object). So try:

template <class T>
std::ostream &operator << (std::ostream &Output, const Child<T> &Object)
{ ... }

That should get you farther along.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
Mike Housky
  • 3,959
  • 1
  • 17
  • 31
1

The cleanest way is:

template <class T>
class Child {
   void print(std::ostream& os)const;
public:       
  friend std::ostream &operator << (std::ostream &Output, const Child &Object){
    Object.print(Output);
    return Output;
  }
};
// implement Child<T>::print here

a minimal amout of "glue" inline in the friend operator, forwarding to a conventional method with the meat in it.

This makes the syntax obvious to readers, and I find non-template friends of templates to be more sane than the other alternatives (like template friends to template types).

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
1

Firstly, since class templates typically need to be defined in a header (in order to use them effectively from multiple source files) remove the using namespace std and refer to ostream as std::ostream. A quick search will find numerous explanations of why using directives (like using namespace std) are best avoided in header files.

This means changing the class definition to

template <class T> class Child
{

    public:
    
    friend std::ostream &operator << (std::ostream &Output, const Child &Object);

};

The definition of the function (outside the class definition) may then be changed to

template<class T> std::ostream &operator << (std::ostream &Output, const Child <T> &Object)
{
      // presumably operations that stream members of Object to Output in some way

      return Output;
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
Peter
  • 35,646
  • 4
  • 32
  • 74
  • I get a warning that says "warning: friend declaration ‘std::ostream& operator<<(std::ostream&, const Child&)’ declares a non-template function [-Wnon-template-friend]" I'm not quite sure how to proceed from here. How do I get rid of the warning? – James Brodski Nov 29 '20 at 15:54
  • The code you have provided does not refer to `Child`. Neither does the code sample I have provided. Without information on the context in which *your* code refers to `Child` it is impossible to guess why you are getting that warning. Whatever you have done, it is not consistent with the approach I described. – Peter Nov 30 '20 at 09:20