C++11 – When is Const Reference Better Than Pass-by-Value

c++c++11

I have some pre-C++11 code in which I use const references to pass large parameters like vector's a lot. An example is as follows:

int hd(const vector<int>& a) {
   return a[0];
}

I heard that with new C++11 features, you can pass the vector by value as follows without performance hits.

int hd(vector<int> a) {
   return a[0];
}

For example, this answer says

C++11's move semantics make passing and returning by value much more attractive even for complex objects.

Is it true that the above two options are the same performance-wise?

If so, when is using const reference as in option 1 better than option 2? (i.e. why do we still need to use const references in C++11).

One reason I ask is that const references complicate deduction of template parameters, and it would be a lot easier to use pass-by-value only, if it is the same with const reference performance-wise.

Best Answer

The general rule of thumb for passing by value is when you would end up making a copy anyway. That is to say that rather than doing this:

void f(const std::vector<int>& x) {
    std::vector<int> y(x);
    // stuff
}

where you first pass a const-ref and then copy it, you should do this instead:

void f(std::vector<int> x) {
    // work with x instead
}

This has been partially true in C++03, and has become more useful with move semantics, as the copy may be replaced by a move in the pass-by-val case when the function is called with an rvalue.

Otherwise, when all you want to do is read the data, passing by const reference is still the preferred, efficient way.