Overloading the signature inference operator

do you know how to write a function or method signature for the <<operator for a template class in C ++? I want something like:


template <class A> class MyClass{
  public:
    friend ostream & operator<<(ostream & os, MyClass<A> mc);
}
ostream & operator<<(ostream & os, MyClass<A> mc){
  // some code
  return os;
}

      

But this just won't compile. Do anyone know, how to write it correctly?
+2


a source to share


1 answer


All of the following, if you don't need an operator to be a friend, don't be a friend. For inference operators in particular, in my opinion, you shouldn't make them friends. This is because if your class can be streamed, it must have equivalent functions get

that programmatically expose the same data. And in that case, you can write operator<<

as a non-friend in terms of those functions get

.

If you have a good reason to make them friends, you can make a friend definition

template <class A> class MyClass {
  public:
    friend ostream & operator<<(ostream & os, MyClass<A> const& mc) {
      // ...
    }
};

      

This way you don't need the clause template<...>

that the type receives A

. This is known if you define an operator inside a template. Note that even though you defined it inside a template, it is not a member function. It is still not a member, but it has access to the names declared in the class (such as a template parameter). For every instance MyClass

you create, from this friend function that prints things out, another operator function is created, different from the template.

If you want to define a template externally, you must predefine it to be able to declare a given specialization as a friend.



// predeclare it so you can make it a friend.
template <class A> class MyClass;
template <class A> ostream &operator<<(ostream &os, MyClass<A> const&);

template <class A> class MyClass{
  public:
    /* the "<A>" is needed - it says that a given instantiation of
       that template is a friend, and not a non-template function. */
    friend ostream & operator<< <A>(ostream & os, MyClass<A> const& mc);
};

template <class A> 
ostream & operator<<(ostream & os, MyClass<A> const& mc){
  // some code
  return os;
}

      

It makes a operator<< <Foo>

friend MyClass<Foo>

. If you were to omit <A>

or also possibly empty <>

, the compiler would figure it out, saying that you made a non-template statement containing a concrete instead of template parameters as a friend.

An easier but less "correct" solution is to make MyClass <Foo>

all instances as a friend operator <<

. operator << <Bar>

Could theoretically access private members MyClass <Foo>

. This is not what you want, but it works too, getting more access than you need. This eliminates the need for a forward declaration:

template <class A> class MyClass{
  public:
    /* make all instantiations friends. */
    template<typename T>
    friend ostream & operator<<(ostream & os, MyClass<T> const& mc);
};

template <class T> 
ostream & operator<<(ostream & os, MyClass<T> const& mc){
  // some code
  return os;
}

      

+6


a source







All Articles