I keep getting an error when trying to use a matrix class someone else wrote about 10 years ago in VC++ 6.0:
Optimizer.cpp:48: error: no matching function for call to 'matrix<double>::matrix(matrix<double>)'
Matrix.h:16: note: candidates are: matrix<T>::matrix(matrix<T>&) [with T = double]
The following is the code with most of the irrelevant stuff removed.
We often write this off as initialization--meaning a constructor call. If my understanding is correct, this actually creates a temporary and then uses the copy constructor (which does not exist in this case) to construct trainPredictY.
kbw, now it gives me this error: Matrix.cpp:47: error: passing 'const matrix<double>' as 'this' argument of 'vect<T> matrix<T>::get_row(int) [with T = double]' discards qualifiers
vect is another class with similar functions as matrix, just for one dimension
moorecm, it gives me a similar error:
Optimizer.cpp:48: error: no matching function for call to 'matrix<double>::matrix(matrix<double>)'
Matrix.h:16: note: candidates are: matrix<T>::matrix(matrix<T>&) [with T = double]
Matrix.h:15: note: matrix<T>::matrix(int, int) [with T = double]
Matrix.h:14: note: matrix<T>::matrix() [with T = double]
He is not returning a temp. The returned object is a copy (no & in the returned value).
I'm not sure but the template says class and not typename. Maybe that's a problem since you are passing double (not a class). Maybe you should post more code (the matrix class would be good and the optimizer).
Unfortunately, your original matrix class was not written with const-correctness in mind. The get_row() member should be declared as a const function, but it is not, so the compiler is complaining that you are using a function that does not promise to leave the matrix unchanged. However, you are trying to use it on a const matrix...
Take a few minutes to look through the class and affix "const" to all the functions that do not modify the class. For example:
#include "Vect.h"
template<class T>
class matrix
{
public:
matrix();
matrix(int i, int j);
matrix(matrix<T> &x);
~matrix();
int get_row_size(void);
int get_col_size(void);
vect<T> get_row(int _row);
void set_row(int _row, vect<T> _vect);
void set_dim(int i, int j);
operator vect<T> ();
T &operator()(int i, int j);
matrix<T> &operator=(matrix<T> &x);
private:
int rows;
vect<T> *pt;
};
jsmith is correct I believe, and the returned value IS a temp, although the second solution won't work because the assignment operator is also explicitly defined to take a non-const reference to a matrix (i.e., same problem).
You could make it work using the rather-convoluted code below
#include "Vect.h"
template<class T>
class matrix
{
public:
matrix();
matrix(int i, int j);
matrix(const matrix<T> &x);
~matrix();
int get_row_size(void) const;
int get_col_size(void) const;
vect<T> get_row(int _row) const;
void set_row(int _row, vect<T> _vect);
void set_dim(int i, int j);
operator vect<T> () const;
T &operator()(int i, int j);
matrix<T> &operator=(matrix<T> &x);
private:
int rows;
vect<T> *pt;
};
Hope this helps.
[edit]
The point is that things that simply return non-modifiable information should be const.
@RedX: I think you don't understand what a temporary is. Your example above is completely backwards.
The first one will produce the error; the second one won't (assuming of course that the second is one is
fixed, since it will generate a compile warning about returning a reference to a local variable).
Often the temporary is omitted by the compiler when it is bound in the initialization of another object. From man g++:
-fno-elide-constructors
The C++ standard allows an implementation to omit creating a temporary which is only used to initialize another object of the same type. Specifying this option disables that optimization, and forces G++ to call the copy constructor in all cases.
If you specify this option, write a class that outputs something in the copy constructor, you'll see that your function
Actually calls the copy constructor twice - once when the function returns (when creating the temporary anyClass), and once when initializing the object using the return value.
I've been heading in that direction, but my last dealings with it didn't go so well. I think I am going to break it all down into flowchart/pseudocode and then think about how to do it. One other concern though is speed, and I know that a hand written vector and matrix class in C with only what you need is likely faster than importing and using STL.
But, to answer OP's question, any parameter passed by (non-const) pointer or by
(non-const) reference that the function does not intend to modify in the caller
should be passed by const pointer or const reference. The following member
functions should be fixed: