Friends, templates, overload <<

I am trying to use friend functions to overload <<and patterns to familiarize myself with patterns. I do not know what these compilation errors are:

 Point.cpp:11: error: shadows template parm 'class T' Point.cpp:12: error: declaration of 'const Point<T>& T' 

for this file

 #include "Point.h" template <class T> Point<T>::Point() : xCoordinate(0), yCoordinate(0) {} template <class T> Point<T>::Point(T xCoordinate, T yCoordinate) : xCoordinate(xCoordinate), yCoordinate(yCoordinate) {} template <class T> std::ostream &operator<<(std::ostream &out, const Point<T> &T) { std::cout << "(" << T.xCoordinate << ", " << T.yCoordinate << ")"; return out; } 

My title looks like this:

 #ifndef POINT_H #define POINT_H #include <iostream> template <class T> class Point { public: Point(); Point(T xCoordinate, T yCoordinate); friend std::ostream &operator<<(std::ostream &out, const Point<T> &T); private: T xCoordinate; T yCoordinate; }; #endif 

My title also gives a warning:

 Point.h:12: warning: friend declaration 'std::ostream& operator<<(std::ostream&, const Point<T>&)' declares a non-template function 

Which I also did not know why. Any suggestions? Thanks.

+4
source share
3 answers

Both template parameters and function parameters have the same name. Change it to something like:

 template <class T> std::ostream &operator<<(std::ostream &out, const Point<T> &point) { std::cout << "(" << point.xCoordinate << ", " << point.yCoordinate << ")"; return out; } 

The friend function declaration in the header should also be changed:

 template <class G> friend std::ostream &operator<<(std::ostream &out, const Point<G> &point); 
+3
source

@ Firas has already answered your first question, so I won’t repeat it here.

For your second question, he warns you about this:

 friend std::ostream &operator<<(std::ostream &out, const Point<T> &T); 

This declaration is in the class template:

 template <class T> class Point { // ... 

This tells you that even if you can create a Point instance for many different types, you say that the non-tplate operator<< is a friend to everyone. If there is a potentially unlimited set of different types of Point s, you said there is only one operator<< for them.

In fact, this seems to be a mistake in your code - you defined operator<< as a function template, but declared (not a template) function as a friend of the class (one that your code does not seem to define). IOW, this definition:

 template <class T> std::ostream &operator<<(std::ostream &out, const Point<T> &T) 

... has a template that does not match what you indicated in the friend’s ad above (although I think you intended to match them).

+1
source

You have a small (unrelated) error here: defining template methods is best done in the header because they should (usually) be visible to the caller.

For your compilation problem: as the warning says, you are trying to declare a friend function without a template. If you fix this, the problem will be magically resolved.

 template <class T> class Point { public: template <class U> friend std::ostream& operator<<(std::ostream& out, const Point<T>& p); }; 

But the real question is: do you need a friend declaration here? Of course, the x and y coordinates are available to the public (at least in read-only mode)?

 // Free functions template <class T> std::ostream& operator<<(std::ostream& out, const Point<T>& p) { return out << '(' << px() << ", " << py() << ')'; } 

Finally, note that it would be better if your argument had a different name from the types in the scope and, in particular, the types that you declared using the template syntax.

0
source

Source: https://habr.com/ru/post/1311703/


All Articles