I am trying to get a better understanding on some advanced staffs of C++. I am trying to understand stream operator overloading
, friend function
and template
now. I am trying to learn all these things in a single code segment.
So, I am trying to implement a template class
which will just contain an array
, which I want to populate with stream operator
. So,I came up with this.
#include <iostream>
using namespace std;
template<class T, int L>
class TestClass
{
private:
T data[L];
public:
friend void operator>>(const istream&, const TestClass<T,L>&);
};
template<class T, int L>
void operator>>(const istream& in, const TestClass<T,L>& q)
{
for(int i = 0; i < L; i++)
{
in >> q.data[i];
}
}
int main() {
TestClass<float, 3> Q;
cin >> Q;
return 0;
}
This is pretty easy code segment. But, I am getting following error on compilation
undefined reference to `operator>>(std::istream const&, TestClass<float, 3> const&)'
with the following warning
warning: friend declaration 'void operator>>(const istream&, const TestClass<T, L>&)' declares a non-template function [-Wnon-template-friend]|
I know, I am doing some rookie mistake, as I am pretty new to this things. It will be great if someone helps to run this successfully.
The issue is two-fold:
friend
function should also be a templateistream
and TestClass
as const. Remove thatHere is updated code:
template<class T, int L>
class TestClass
{
private:
T data[L];
public:
template<class U, int M>
friend void operator>>(istream&, TestClass<U,M>&);
};
template<class T, int L>
void operator>>(istream& in, TestClass<T,L>& q)
{
for(int i = 0; i < L; i++)
{
in >> q.data[i];
}
}
Slightly different syntax to declare the friend and everything will work Demo:
template<class T, int L>
class TestClass
{
private:
T data[L];
public:
friend void operator>> <>(istream&, TestClass&);
};
(Thanks @chris). This format (with the <>
) differs from the above example in that the above is technically declaring all instantiations of operator>>
to be a friend
whereas this one only has a one-to-one relationship.
Alternatively you could include the definition along with the friend declaration Demo:
template<class T, int L>
class TestClass
{
private:
T data[L];
public:
friend void operator>>(istream& in, TestClass& q){
for(int i = 0; i < L; i++)
{
in >> q.data[i];
}
}
};