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

余生颓废 提交于 2019-12-06 11:20:28

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.

MSVC template code is fundamantally broken. They have been rebuilding it over the last few years, but it still contains quirks like what you are observing. This is because it was built to be almost macro like, instead of being what the C++ standard required.

In gcc you can do away with the forward declarations by defining the << operator inline in the body of the class:

friend std::ostream& operator<<(std::ostream& c, const A& v){
  c << v._v;
  return c;
}

this has the advantage that << becomes no longer a template, but rather a distinct non-template created for each instance of the template A. In some scenarios this tends to work better.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!