Friends, templates, overloading <<
I'm trying to use friend functions to overload << and templates to get familiar with templates. I do not know what these compile 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() : xCoordinat开发者_开发技巧e(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 header looks like:
#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 header also gives the warning:
Point.h:12: warning: friend declaration 'std::ostream& operator<<(std::ostream&, const Point<T>&)' declares a non-template function
Which I was also unsure why. Any thoughts? Thanks.
Both the template parameter and the function parameter 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 declaration of the friend function in the header should be changed too:
template <class G>
friend std::ostream &operator<<(std::ostream &out, const Point<G> &point);
@Firas has already answered your first question, so I won't repeat that here.
For your second question, it's warning you about this:
friend std::ostream &operator<<(std::ostream &out, const Point<T> &T);
This declaration is in a class template:
template <class T>
class Point { // ...
It's telling you that even though you can instantiate Point
over many different types, you're saying that a non -template operator<<
is a friend to all of them. I.e., even though there is a potentially unbounded set of different kinds of Point
s, you've said there's only one operator<<
for them.
In fact, this appears to be a mistake in your code -- you've defined operator<<
as a function template, but declared a (non-template) function as the friend of the class (one that your code doesn't seem to define). IOW, this definition:
template <class T>
std::ostream &operator<<(std::ostream &out, const Point<T> &T)
...is of a template, which is not the same thing as you've pointed to in the friend declaration above (even though I think you intended them to match).
You have a subtle error here (unrelated): the definition of template methods are best tucked in the header because they should (usually) be visible to the caller.
For your compile issue: as the warning says, you are attempting to declare a non template friend function. Should you correct it, then the problem would magically be solved.
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 ? Surely the x
and y
coordinates are accessible 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 << '(' << p.x() << ", " << p.y() << ')';
}
Finally, do note that it would be best if your argument had a different name from the types in the scope, and notably the types you declared using the template
syntax.
精彩评论