I'm converting some functions from Matlab to C++, and there are something to do with matrix. I found this simple function somewhere on the Internet:
typedef std::vector<std::vector<double> > Matrix;
Matrix sum(const Matrix& a, const Matrix& b) {
size_t nrows = a.size();
size_t ncols = a[0].size();
Matrix c(nrows, std::vector<double>(ncols));
for (int i = 0; i < nrows; ++i) {
for (int j = 0; j < ncols; ++j) {
c[i][j] = a[i][j] + b[i][j];
}
}
return c;
}
Can anyone explain me why they used const Matrix& a
as the input, instead of Matrix a
? Are they using it as a habit, or is there any benefit of using it since I did not see any difference between the results of 2 versions (const Matrix& a
and Matrix a
as input).
What you don't see is without profiling the code and looking for differences in performance is what is happening behind the scenes.
A
Matrix a
parameter is pass by value. The sourceMatrix
will be copied intoMatrix a
, and depending on the size of the matrix, this may take a while. A 3x3 matrix isn't much, but if it happens a lot... And if instead of 3x3 you have a 300x300 matrix, that is a lot of vector construction and data copying. Probably going to be a performance killer. It will almost certainly certainly take longer than the pass by reference version of the function,const Matrix& a
which will only copy the address of the sourceMatrix
unless the compiler sees some advantages in performing a copy of theMatrix
itself.So you could get by with
Matrix & a
, but that allows the function to play with the contents ofMatrix a
, possibly to the detriment of the calling function. Changing the declaration toconst Matrix & a
promises the caller thata
will not be changed inside the function and the compiler backs this up by refusing to compile if you try. This is mostly a safety thing. It prevents the possibility of subtle mistakes introducing hard-to-detect errors.<=pointer-size
data type on a given platform.const
is to make sure that given object will not be changed by function, which is a safety-check for the programmer writing given function, a contract for the caller. It also makes the caller to pass a non-const as well as const object.const
without reference doesn't make sense (as original object will not be modified anyway). But, as a safety-net, it is advised for function implementer to haveconst
parameters, so that by mistake function doesn't change its arguments. That's the reason, some functional languages haveconstness
by default (unless you make them mutable).