In this Stack Overflow question (which has unfortunately been put on hold since I began researching for this question), several people have mentioned that "in modern C++," due to move semantics, there's no need for the compiled code to copy the string for the operation string = string + s1
, leaving the impression that with a modern C++ compiler, string = string + s1
can be just as efficient as string += s1
. I find that claim dubious, but I'm working in the legacy world of C++03 and still don't know much about move semantics. (It's my job, and I don't pick our compiler.)
Cost of string += s1
With the operation string += s1
, no new allocation is needed unless the expansion of string
's buffer exceeds its previously allocated capacity, and assuming a reasonable implementation of the string class, no temporary object is ever created in the operation string += s1
. Assuming the size of the result fits within that previously allocated capacity, the most costly part of string += s1
is the appending (copying) of s1
's content to the end of string
's original content using previously allocated but unused space. Also note that the cost of that copy operation is just the number of bytes of s1
, not the combined total number of bytes.
Cost of string = string + s1
in legacy C++ (C++03 & earlier)
In legacy C++ (03 and earlier), string = string + s1
would, in my understanding, require at least one temporary allocation (for the evaluation of string + s1
), and two full copies of the sum of the number of bytes in s1
and the original string
(1. copy original content of string
to the temporary and copy-append the bytes of s1
to the end of those bytes in the temporary, and then 2. copy all of the resulting bytes from the temporary back to string
's buffer, including the bytes of the original content which were already there anyway). Obviously that's far more expensive than the cost of string += 1
described above, and it could make a significant difference especially if the append operation is performed many times in a loop (it's the Shlemiel the painter algorithm, except it's even worse than the inefficiency of strcat()
!).
Cost of string = string + s1
in "modern" C++ (C++11 (or C++14?) & later)
It seems to me that the evaluation of the expression string + s1
will produce an rvalue, which can subsequently be provided as an rvalue reference to string
's move assignment operator, eliminating the need to copy the result of string + s1
back into string
. But that doesn't eliminate the need to create the original temporary object, and the associated copying for it, does it? In my thinking, the best that move semantics can do is eliminate one of the two full copy operations. One allocation and one copy operation (to create the temporary) is still required, right? If so, then move semantics only makes code like that "less bad", it doesn't stop it from being another instance of the Shlemiel the painter algorithm, and it's still worse than C's strcat()!
Please tell me I'm wrong. Also: Please don't speculate. That's not helpful. If your answer or comment begins with "I think...", then please don't submit it.