Search code examples
c++visual-studiotemplatesg++friend

why does g++ need both definitions of template class and its friend function?


I want to write a friend function for a template class. In visual studio, I can ignore the pre-definition both. But in g++, it is mandatory. Why?

#include <iostream>
using namespace std;
// g++ needs, vs do not needs
template <class T>
class A;

template <class T>
ostream & operator<<(ostream & c, const A<T> & v);
//- end of g++ needs

template <class T>
class A {
    T _v;
public:
    A() {}
    A(T v) : _v(v) {}
    friend ostream & operator<<<T>(ostream & c, const A<T> & v);
};
template <class T>
ostream & operator<<(ostream & c, const A<T> & v) {
    c << v._v; return c;
}

Solution

  • Because

    friend ostream & operator<<<T>(ostream & c, const A<T> & v);
    

    is a specialization of

    template <class T>
    ostream & operator<<(ostream & c, const A<T> & v);
    

    you need to declare that first and the

    A<T>
    

    part means you have to declare that too before the operator declaration

    template <class T>
    class A;
    

    So VS is probably wrong as C++14

    14.5.4 Friends [temp.friend] 
    

    gives the example

    template<class T> class task;
    template<class T> task<T>* preempt(task<T>*);
    
    template<class T> class task {
      friend void next_time();
      friend void process(task<T>*);
      friend task<T>* preempt<T>(task<T>*);
      template<class C> friend int func(C);
    
      friend class task<int>;
      template<class P> friend class frd;
    };
    

    Where your example fits the 3rd friend declaration.