friend declaration declares a non-template function [duplicate]

折月煮酒 提交于 2019-11-27 11:46:23

It sounds like you want to change:

friend ostream& operator << (ostream& out, const Base<T>& e);

To:

template<class T>
friend ostream& operator << (ostream& out, const Base<T>& e);

Gcc is rightly warning you. Despite it's appearances (it takes Base argument), it is not a function template.

Your class definition has a non-template declaration of the friend function (without the template), but the friend function definition later on is a function template (i.e. starts with template..).

Also your operator<< takes a Base *. This is not correct. It should be Base const & to retain it's built-in semantics

Probably you are looking at something as below:

template <typename T> 
class Base { 
  public: 
    friend ostream& operator << (ostream &out, Base<T> const &e){
       return out;
    }; 
}; 

int main(){
   Base<int> b;
   cout << b;
}

If you want fully templated, then this is probably what you want. But I am not sure how much useful this is over the previous one. Since the lookup involves ADL, you will never be able to resolve to any condition where T is not equal to U (as long as the call is from a context not related to this class e.g. from 'main' function)

template <typename T>  
class Base {  
  public:  
    template<class U> friend ostream& operator << (ostream &out, Base<U> const &e){ 
       return out; 
    };  
};

int main(){ 
   Base<int> b; 
   cout << b; 
} 

Probably what you are looking for is:

template <typename T>
class Base;

template <typename T>
ostream& operator<< (ostream &, const Base<T>&);

template <typename T>
class Base
{
  public:
    template<>
    friend ostream& operator << <T>(ostream &, const Base<T> &);
};

template <typename T>
ostream& operator<< ( ostream &out, const Base<T>& e )
{
    return out << e->data;
}

This friends only a single instantiation of the template, the one where the operator's template parameter matches the class's template parameter.

UPDATE: Unfortunately, it's illegal. Both MSVC and Comeau reject it. Which raises the question of why the original error message suggested pretty much EXACTLY this approach.

changing

friend ostream& operator << (ostream& out, const Base<T>& e);

to

friend ostream& operator << <T>(ostream& out, const Base<T>& e);

should work as well--I just solved an identical problem in this way.

changing

friend ostream& operator << (ostream &out, Base<T> *e)`

To

template<T> friend ostream& operator << (ostream &out, Base *e)

change

ostream& operator<< (ostream &out, Base<int> *e) {
    out << e->data;
    return out;
}

to

ostream& operator<< (ostream &out, T *e) {
    out << e->data;
    return out;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!