Generally:
[...] the compilers are permitted, but not required to omit the copy [...]
Anyway your function should be optimised by any modern compiler because copy elision.
Here an example:
The result of the operator+
is in the assembly section:
call operator+(BigClass const&, BigClass const&)
addl $12, %esp
As you can see, no copy constructor is invoked in order to copy the result.
Indeed, if we disable the copy elision optimisation in GCC, the result changes:
call operator+(BigClass const&, BigClass const&)
addl $12, %esp
subl $8, %esp
leal -20(%ebp), %eax
pushl %eax
leal -56(%ebp), %eax
pushl %eax
call BigClass::BigClass(BigClass&&)
addl $16, %esp
subl $12, %esp
leal -20(%ebp), %eax
pushl %eax
call BigClass::~BigClass()
addl $16, %esp
After the call of operator+
the copy (or move in this case) constructor is called, and after the destructor of the temporary object.
Note that the copy elision is obtained even disabling optimisations (-O0
).
The same result is obtained with an older version: GCC 4.4.7.
Since copy elision is not guaranteed for all architectures, you might implement some different solutions.
One possible solution is to avoid the allocation of a temporary variable inside the function, demanding the caller the reservation of that space.
In order to do that, you should use a "custom" method and avoid to overload the operator+
.
void sum_bigClasses(const BigClass& obj1, const BigClass& obj2, BigClass& output) {
// output.resize(obj1.size() + obj2.size());
// std::copy(...);
}
Another solution it could be to implement a non-const operator for sum. An example:
BigClass& operator+=(const BigClass& rhs) {
// std::copy(rhs.cbegin(), rsh.cend(), std::back_inserter(abc));
return *this;
}
In this way the class interface allows different strategies:
- Avoid to allocate 3 different object but only 2, if you don't need to preserve all different states.
- Allow to allocate 3 different object and avoid temporary construction inside the operator.
Here, the two examples.
The first point:
BigClass o1;
BigClass o2;
// Fill o1 and o2;
o1 += o2;
// only 2 object are alive
The second point:
BigClass o1;
BigClass o2;
// Fill o1 and o2;
BigClass o3 = o1; // Costructor from o1
o3 += o2;
// three different object
EDIT:
Since the function it's a NRVO (the returned expression is not a prvalue) neither the new standard C++17 will guarantee the copy elision.