Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ - why `const type& variable` as function input?

Tags:

c++

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).

like image 226
scmg Avatar asked Apr 02 '16 06:04

scmg


2 Answers

  • Reference is to avoid copying large size objects. However, for small objects, it is more preferable to have non-reference, since reference-creation will incur more overhead than it would save. For example <=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.
  • Some may argue that 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 have const parameters, so that by mistake function doesn't change its arguments. That's the reason, some functional languages have constness by default (unless you make them mutable).
like image 73
Ajay Avatar answered Nov 14 '22 22:11

Ajay


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 source Matrix will be copied into Matrix 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 source Matrix unless the compiler sees some advantages in performing a copy of the Matrix itself.

So you could get by with Matrix & a, but that allows the function to play with the contents of Matrix a, possibly to the detriment of the calling function. Changing the declaration to const Matrix & a promises the caller that a 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.

like image 44
user4581301 Avatar answered Nov 14 '22 22:11

user4581301