+ 2
Compilation Error
In this matrix class when I use << and >> overloaded operator compiler generates the error. I don't understand what is happening. Check this. https://code.sololearn.com/cJv5jjET69H2/?ref=app [EDITED] Next bug. same problem. with multiplication operator. Check line 45, 430 and 490.
15 Answers
+ 6
The errors are in fact raised by all the friend functions and friend operator overloads.
In a normal class, any function not supposed to be part of the class which is to be allowed to access the class's private members can be marked as a friend. But in a template class, marking a function as friend like this:
template<class T> class Matrix
{
friend ostream& operator<<(ostream&, const Matrix&);
};
won't work, as the class Matrix without the specialization type, does not exist. Thus the Matrix class will have to specify in detail which specialization of the template class is to be declared as friend. Thus, one of the ways to declare the function as friend is to use a new template argument:
template<class T> class Matrix
{
template<class U> friend ostream& operator<<(ostream&, const Matrix<U>&);
};
This declares all possible specializations of the operator for the class Matrix as friends.
+ 7
Another way is to inline the code inside the friend function by defining the function along with the declaration:
template<class T> class Matrix
{
friend ostream& operator<<(ostream& os, const Matrix& m)
{
m.output(os); return os;
}
};
But this might not work, depending on the function's complexity (if it can be made inline or not).
The standard way however is to first forward declare the class and the friend functions (declare as prototypes), and then mark the function inside the class as friend:
// Forward declaration of class
template<class T> class Matrix;
// Forward declaration of function
template<class T> std::ostream& operator<<(std:: ostream &, const Matrix &);
template<class T> class Matrix
{
friend ostream& operator<< <>(ostream&, const Matrix<T>&);
};
Notice the empty <> before the parenthesis, which is used to indicate that we only befriend the specialization of the function with the same type as the type we used to initialize the class. Thus, we use the same variable, T.
+ 6
The problem with the * overload was that it was trying to access temp.numRows and other private members of the class. Though its a friend, its allowed to access members of the class Matrix<U>, and not Matrix<T>. Even if T and U are same, during compilation, this will not be known completely and thus the error is shown. On the other hand << and >> use public methods available to both Matrix<T> and Matrix<U>. So the overload works without an issue. But if one of them tries to access a private member, the same errors will be raised as in the case of *.
+ 5
C +-, As of now, the error is due to line 48, which is:
template<class U>friend Matrix<T> operator * (const T d, const Matrix<T> &m);
This raises an error due to the problem of befriending Matrix<U> but not Matrix<T> as discussed before.
The solution is to change this line to:
template<class U>friend Matrix<U> operator * (const U d, const Matrix<U> &m);
In case this has been tried or the friend variant was removed, kindly update the code provided with the question to reflect the changes.
+ 3
Thanks for the help.
now it is working.
But there are always bugs. some other identified.
😂😂🤣🤣
+ 3
C +-
The code you have shared works fine after removing the = after the ) at line 235, and changing c = 2*c to c = c*2.
You can verify the same by making changes in the code you have shared or running:
https://code.sololearn.com/cN4kvL8dSNPd/?ref=app
+ 2
C +- In the friend operator's prototype after line 45, you accidentally used the template argument T, where you should be using U (T cannot be used unless you forward declare the class and function).
+ 1
Now not compiling on multiplication operator.
line 430 and 490 and 45.
Check the code.
+ 1
Okay. But this works with << >> here I used Matrix<T>.
Is this necessary only for built in data types?
+ 1
That's fine. But I have removed friend function then tried but problem is with other two * operators.
+ 1
https://code.sololearn.com/cJv5jjET69H2/?ref=app
Now check.
Problem images
https://ibb.co/qkrMRKF
https://ibb.co/k6rwHXx
+ 1
C +- For 2*c to work you need the friend operator. The rules are the same in this case. Operators overloaded as normal methods require the object of the type on the left and the second operand on the right.
To get 2*c to work, uncomment the friend version and replace T with U in the declaration inside the class.
+ 1
Problem is solved.
You can add explicit to first constructor:
explicit Matrix<T>( int = 0, int = 0 );
It will also prohibit constructs like
Matrix<int> m = 1234;
By the way, you can also extend the class for the case of ‘Matrix<T> && m’ parameters.
Now check the code.
https://code.sololearn.com/cJv5jjET69H2/?ref=app
0
Kinshuk Vasisht This is fine.
It works with c*2 but whats about 2*c ? I'm facing trouble with this situation.
In one condition it works from the first day but I want to overload operator so that it works in both conditions.
And I'm in trouble.
Maybe the language I learnet in University. Its lectures videos are recorded in 2002 and now the language rules are changed. ? 🤔🤔
- 1
Problem was that.
the compiler was considering "Matrix<T> &m" and "T d" parameters as the same type, therefore, it was not overloading.