Trying to study C++ function templates. As a part of which I have this code below. It works fine, but I have questions as below :-
1] Why is the operator << overloading function need to be friend ? If I remove the keyword friend it gives compilation error saying : operator << has too many parameters.
2] Why does the operator << overloading function need to return a reference to ostream object which is also an input argument to it?
3]I doubt this, but Do the above 2 questions have got anything to do with the fact that the function templates are used for a user defined class which has overloaded functions?
template <class T>
T Average(T *atArray, int nNumValues)
{
T tSum = 0;
for (int nCount=0; nCount < nNumValues; nCount++)
tSum += atArray[nCount];
tSum /= nNumValues;
return tSum;
}
class Cents
{
private:
int m_nCents;
public:
Cents(int nCents)
: m_nCents(nCents)
{
}
//Why is friend needed below
//Why does it need to return ostream&, why can't it have void return type, as all it is doing is printing the class private member.
friend ostream& operator<< (ostream &out, const Cents &cCents)
{
out << cCents.m_nCents << " cents ";
return out;
}
/*
void operator <<( const Cents &cCents) //did not work - compilation errors
{
cout << cCents.m_nCents << " cents ";
}
*/
void operator+=(Cents cCents)
{
m_nCents += cCents.m_nCents;
}
void operator/=(int nValue)
{
m_nCents /= nValue;
}
};
int main()
{
int anArray[] = { 5, 3, 2, 1, 4 };
cout << Average(anArray, 5) << endl;
double dnArray[] = { 3.12, 3.45, 9.23, 6.34 };
cout << Average(dnArray, 4) << endl;
Cents cArray[] = { Cents(5), Cents(10), Cents(15), Cents(14) };
cout << Average(cArray, 4) << endl;
cin.get();
return 0;
}
<<alters the stream’s state, and hence ideally it should be implemented as member of it’s left operand’s type. However, its left operands are streams from the standard library, and while most of the stream output and input operators defined by the standard library are indeed defined as members of the stream classes, when you implement output and input operations for your own types, you cannot change the standard library’s stream types.That is why you need to implement these(
<<and>>) operators for your own types as non-member functions. Since you need to access the private/protected member variables of your class object inside the operator definition, these overloaded operators are needed to be declared as friend of your class.Returning an reference to standard stream object allows you to have Object Chaining.
You can have calls like:
Templates help you implement generic functions and classes which can be called for different
datatypes and the compiler takes care of generating the code for those specific data types. So the above two points are not related.
Strongly suggest reading this FAQ entry:
Operator overloading