Question

Possible Duplicate:
Is pass-by-value a reasonable default in C++11?

I'm reading Want Speed? Pass by Value. by Dave Abrahams about copy elision and RVO. And I'm wondering why do we need the copy elision?

I have been told too many times that you should pass function arguments by const reference to avoid copying (nearly every c++ book I read told me about this).

Suppose we have two functions:

int f1(const string &s);
int f2(string s);

If the actual argument is an rvalue, copying will be avoided in both functions. But if the actual argument is an lvalue, copying will only be avoided in f1, not in f2. So why do we need this feature?

Was it helpful?

Solution

Pass by value if you need a copy anyway. Whether you choose f1's signature or f2's signature depends upon the contents of the function. For example, you would use a const reference in this case:

int f1(const string& s) {
    return s.size();
}

But you would pass by value in this case:

int f2(string s) {
    sort(s.begin(), s.end());
    s.erase(unique(s.begin(), s.end()), s.end());
    return s.size();
}

because the alternative would be this:

int f2(const string& s) {
    string temp(s);
    sort(temp.begin(), temp.end());
    temp.erase(unique(temp.begin(), temp.end()), temp.end());
    return temp.size();
}

OTHER TIPS

RVO doesn't apply to your example because the return value is int.

string f1(const string &s) {
    string ret = s; // always makes a copy
    ret += 'x';
    return ret; // makes a copy pre-C++11 if no RVO
}

Tally: 1-2 copies in C++03, exactly 1 in C++11 plus (if elision is disabled) a move which may degenerate to a copy for some other class than std::string.

string f2(string s) { // calling makes a copy if lvalue or no elision
    s += 'x';
    return s; // makes a copy pre-C++11 if no RVO
}

Tally: 0-2 copies in C++03, or 0-1 in C++11.

As others have said, pass by value when you want to manipulate the object as a pure value, without any reference semantics.

const & is a familiar idiom, but it's a bit of a kludge in terms of language semantics. You use it when you don't want a reference at all; the & just serves to make the const meaningful in the parameter definition. If you want to modify the parameter (but only locally), then const doesn't really apply, and also the & drops out too.

f2 signals by its signature, no matter what you pass to me, I will deal with my own copy of your object. Useful, if f2 is going to modify the object in a non reversible way (e.g. steal it's resources by moving), or in some concurrency scenarios. Admittedly, c++11 adds new level of confusion to the (already confusing) c++ type system but once you think about it makes a lot of sense...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top