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

孤人 提交于 2019-12-10 10:34:01

问题


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;
}

回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/46986853/why-does-g-need-both-definitions-of-template-class-and-its-friend-function

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