C++ template/ostream operator question
Solution 1
Please look at the error, it says,
friend declaration 'std::ostream& operator<<(std::ostream&, const Vector&)' declares a non-template function|
That means you need to make the operator<<
a template function.
So in the class, you've to declare it as:
template<unsigned short m> //<----note this: i.e make it template!
friend std::ostream& operator <<(std::ostream& out, const Vector<m>& v);
Then define it as,
template <unsigned short m>
std::ostream& operator<<(std::ostream& out, const Vector<m>& v) {
out << "(" << v.coords[1] << " - " << v.coords[2] << ")";
return out;
}
Solution 2
Just define the friend function inside the class.
template <unsigned short n>
class Vector
{
public:
std::vector<float> coords;
Vector();
Vector(std::vector<float> crds);
friend std::ostream& operator <<(std::ostream& out, const Vector& v)
{
out << "(" << v.coords[1] << " - " << v.coords[2] << ")";
return out;
}
};
template <unsigned short n>
Vector<n>::Vector()
{
coords.assign(n, 0.0);
}
int main()
{
Vector<3> toomas;
cout << toomas;
}
Tested: http://ideone.com/LDAR4
Or, declare the template function beforehand, using a forward prototype:
template <unsigned short n>
class Vector;
template <unsigned short n>
std::ostream& operator <<(std::ostream& out, const Vector<n>& v);
template <unsigned short n>
class Vector
{
public:
std::vector<float> coords;
Vector();
Vector(std::vector<float> crds);
friend std::ostream& operator << <>(std::ostream& out, const Vector& v);
};
template <unsigned short n>
Vector<n>::Vector()
{
coords.assign(n, 0.0);
}
template <unsigned short n>
std::ostream& operator <<(std::ostream& out, const Vector<n>& v)
{
out << "(" << v.coords[1] << " - " << v.coords[2] << ")";
return out;
}
Tested: http://ideone.com/8eTeq
Comments
-
Jaanus almost 2 years
trying to get the operator to work, but throwing me bunch of errors:
my header file
template <unsigned short n> class Vector { public: std::vector<float> coords; Vector(); Vector(std::vector<float> crds); friend std::ostream& operator <<(std::ostream& out, const Vector& v); }; template <unsigned short n> Vector<n>::Vector() { coords.assign(n, 0.0); } template <unsigned short n> std::ostream& operator<<(std::ostream& out, const Vector<n>& v) { out << "(" << v.coords[1] << " - " << v.coords[2] << ")"; return out; }
test file
#include <iostream> #include "vector.h" using namespace std; int main() { Vector<3> toomas; cout << toomas; }
error:
C:\CodeBlocks\kool\praks3\vector.h|14|warning: friend declaration 'std::ostream& operator<<(std::ostream&, const Vector&)' declares a non-template function|
C:\CodeBlocks\kool\praks3\vector.h|14|note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) |
obj\Debug\test.o||In function `main':|
C:\CodeBlocks\kool\praks3\test.cpp|8|undefined reference to `operator<<(std::ostream&, Vector<(unsigned short)3> const&)'|
-
Erik about 13 yearsYou mean unsigned short m
-
Nawaz about 13 years@Erik: No I mean, make it template. However, you can choose any name be it
m
,a
,b
. etc. but don't choosen
because it's the argument of enclosing class template! -
Ben Voigt about 13 yearsYuck. Why should
operator <<
forVector<m>
have access to privates ofVector<n>
? -
Nawaz about 13 years@Ben: You've a point. But I was explaining the friend part, and the error he is getting!
-
Erik about 13 years@Nawaz: You do actually mean unsigned short m :P - you used unsigned int m in declaration and unsigned short m in definition
-
Nawaz about 13 years@Erik: Oops.. I thought you were talking about
m
vsn
thingy, when in fact it'sint
vsshort
. Anyway corrected! -
Jaanus about 13 years@Nawaz: well this worked great, thanks, but i do not understand one thing..why doesn't the template before my
class Vector
work for the ostream? why must i write the template twice, but for example i did not have to do that for my constructor. i don't really understand the concept hehe. and why we are using m suddenly, but in constructors we use n. -
Nawaz about 13 years@Jaanus:
template<unsigned short n>
is only for the class, not for the function inside it. If you want to make the function template as well, then you've to do as I said, or do as Ben's solution second is! -
zorro47 almost 5 yearsI've been reading this post as I have a very similar problem. Could you explain why
ostream& operator <<
needs to be initialized and defined inside the class? And also, why it has to be a friend function ? For instance, I can overload operator+=
and I don't have to give the definition inside my class, neither do I have to declare it as a friend. Whyostream& operator <<
is so special? -
Ben Voigt almost 5 years@zorro47: It doesn't have to be a friend function. OP wanted it that way. On the other hand, your comment's comparison to
operator+=
is faulty. First,operator+=
overload CANNOT be a friend, and it CANNOT be a free function, it's required to be a non-static member. Second, foroperator+=
the class instance is the left-hand operand, foroperator<<(ostream&, MyClass&)
the class instance is the right operand. When the class instance is the right operand, you cannot provide the operator as a class member. -
Ben Voigt almost 5 years@zorro47: And right there in my answer has always been an example (second code block) of how to define
operator<<
outside the class, so why are you asking if that is possible? -
zorro47 almost 5 yearsThe method you presented in the second block I figured out on my own as well but it does not work every time I try to apply to my code. However, when I define it as friend inside the class it suddenly starts working. This happens only with
ostream&
Strange to me. That is why I was asking. -
frankelot about 4 yearsI'm having the exact same issue