TITLE: value semantics and efficiency considerations (Newsgroups: comp.std.c++, 11 Jun 97) GRANT: Justin Grant > Getting the results from functions in C++ can be inefficient. Here are the > two common methods: > > // method 1: returning a copy of the funciton's local var > string func_val() ... > > > // method 2: modifying a ref passed into the function > void func_ref(string& ref) ... > > The problem with (1) is that there are one or two extra calls to the copy > constructor required when the value is returned to the caller... > The problem with (2) is that the function must depend on the caller to pass > refs to objects that are in a known state. ... > > Ideally, I'd like to have the efficiency of (2) with the convenience of > (1). Perhaps C++ could have a method for specifying that classes returned > from functions are allocated in the caller but constructed in the function. CLAMAGE: Steve Clamage This approach has been suggested before. The short answer is that it doesn't buy much compared to the optimizations the compiler is already allowed to perform. Basically the complaint boils down to "I want to use value semantics but I don't want to pay the price of value semantics." Viewed that way, you have some choices: 1. Accept the cost of value semantics as in your #1. 2. Don't return values from functions, as in your #2. (Return nothing, or return a reference to a parameter.) 3. Design so that value semantics are not expensive. For example, you can in principle use reference-counted classes which are cheap to copy. The class consists only of a pointer to the counted data (a "helper" or "proxy" class), and all the functions related to copies are inline. Often it takes only a few machine instructions to create or destroy the copy. You can also use a mix of 1 and 2. The canonical problem is with operator+ for some type T. T operator+(const T& left, const T& right) { ... } You pretty much have to return a value, since you don't have a good way to return a pointer or reference, absent garbage collection. You can provide a member operator+= which returns a reference: T& T::operator+=(const T& right) { ... // add right to *this return *this; } Instead of writing t1 = t2 + t3; clients of T can write this, which involves no extra copies: t1 = t2; t1 += t3;