Difference between string += s1 and string = string + s1 [closed]How many copy operations can move semantics save between 'string=string+s1' and 'string+=s1'?What is the difference between #include <filename> and #include “filename”?What are the differences between a pointer variable and a reference variable in C++?How do I iterate over the words of a string?Improve INSERT-per-second performance of SQLite?What is the difference between call and apply?String formatting: % vs. .formatIs the recommendation to include CSS before JavaScript invalid?Why does the order of the loops affect performance when iterating over a 2D array?Image Processing: Algorithm Improvement for 'Coca-Cola Can' RecognitionReplacing a 32-bit loop counter with 64-bit introduces crazy performance deviations

"Valet parking " or "parking valet"

Complaints from (junior) developers against solution architects: how can we show the benefits of our work and improve relationships?

Narset, Parter of Veils interaction with Matter Reshaper

What is this kind of symbol meant to be?

How do discovery writers hibernate?

Coworker mumbles to herself when working, how to ask her to stop?

Why tantalum for the Hayabusa bullets?

Create two random teams from a list of players

What are the cons of stateless password generators?

Why does one get the wrong value when printing counters together?

Scam? Checks via Email

How do I make my photos have more impact?

How did astronauts using rovers tell direction without compasses on the Moon?

Exploiting the delay when a festival ticket is scanned

Why are we moving in circles with a tandem kayak?

Solve equation using Mathematica

Avoiding Implicit Conversion in Constructor. Explicit keyword doesn't help here

What force enables us to walk? Friction or normal reaction?

Are all French verb conjugation tenses and moods practical and efficient?

Why don't short runways use ramps for takeoff?

What is my clock telling me to do?

Can machine learning learn a function like finding maximum from a list?

Why does Earth need water in the Expanse?

Efficiently finding furthest two nodes in a graph



Difference between string += s1 and string = string + s1 [closed]


How many copy operations can move semantics save between 'string=string+s1' and 'string+=s1'?What is the difference between #include <filename> and #include “filename”?What are the differences between a pointer variable and a reference variable in C++?How do I iterate over the words of a string?Improve INSERT-per-second performance of SQLite?What is the difference between call and apply?String formatting: % vs. .formatIs the recommendation to include CSS before JavaScript invalid?Why does the order of the loops affect performance when iterating over a 2D array?Image Processing: Algorithm Improvement for 'Coca-Cola Can' RecognitionReplacing a 32-bit loop counter with 64-bit introduces crazy performance deviations






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








21















One of my programs is exceeding the time limit when I am using fans = fans + s[i], while when I am using fans += s[i] it is being accepted... Why does this happen?
To Explain more , fans is a string and s is also a string so while iterating over string s i want only some characters of s so i am creating a new string fans.Now there are two ways in which i can add character to my new string fans. The Problem is mentioned below



fans = fans + s[i]; // gives Time limit exceeded 
fans += s[i]; // runs successfully









share|improve this question
















closed as off-topic by Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton Jul 22 at 14:24


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Reproducible Example." – Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton
If this question can be reworded to fit the rules in the help center, please edit the question.












  • 1





    One makes a temporary, the other doesn't. Move-assignment can make the former more efficient, but it can't get any better than the later.

    – WhozCraig
    Jul 21 at 10:38







  • 7





    Please extract and provide a minimal reproducible example, your question is off-topic without it. As a new user, also take the tour and read How to Ask.

    – Ulrich Eckhardt
    Jul 21 at 10:43






  • 2





    So fans is an std::string and s[i] is a char? Or is it another string containing a single character?

    – Fabio Turati
    Jul 22 at 1:01






  • 1





    @Naman Have you read Ulrich Eckhardt's comment, and mine? At the very least you should clarify what type fans and s[i] are, but actually it would be better if you edited your question and added a full program (minimal reproducible example) that we can copy and compile. Just check the links that you've been given. It won't take long, and it will improve your question significantly. Thank you!

    – Fabio Turati
    Jul 23 at 0:45






  • 1





    You're not supposed to paste the code of the program you're working on. You are expected to extract a minimal reproducible example from that code and post that. It should be possible to take it and compile it without changes. It shouldn't contain anything that is not necessary to demonstrate the issue. Your question still lacks that, so it is still off-topic.

    – Ulrich Eckhardt
    Jul 24 at 16:31

















21















One of my programs is exceeding the time limit when I am using fans = fans + s[i], while when I am using fans += s[i] it is being accepted... Why does this happen?
To Explain more , fans is a string and s is also a string so while iterating over string s i want only some characters of s so i am creating a new string fans.Now there are two ways in which i can add character to my new string fans. The Problem is mentioned below



fans = fans + s[i]; // gives Time limit exceeded 
fans += s[i]; // runs successfully









share|improve this question
















closed as off-topic by Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton Jul 22 at 14:24


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Reproducible Example." – Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton
If this question can be reworded to fit the rules in the help center, please edit the question.












  • 1





    One makes a temporary, the other doesn't. Move-assignment can make the former more efficient, but it can't get any better than the later.

    – WhozCraig
    Jul 21 at 10:38







  • 7





    Please extract and provide a minimal reproducible example, your question is off-topic without it. As a new user, also take the tour and read How to Ask.

    – Ulrich Eckhardt
    Jul 21 at 10:43






  • 2





    So fans is an std::string and s[i] is a char? Or is it another string containing a single character?

    – Fabio Turati
    Jul 22 at 1:01






  • 1





    @Naman Have you read Ulrich Eckhardt's comment, and mine? At the very least you should clarify what type fans and s[i] are, but actually it would be better if you edited your question and added a full program (minimal reproducible example) that we can copy and compile. Just check the links that you've been given. It won't take long, and it will improve your question significantly. Thank you!

    – Fabio Turati
    Jul 23 at 0:45






  • 1





    You're not supposed to paste the code of the program you're working on. You are expected to extract a minimal reproducible example from that code and post that. It should be possible to take it and compile it without changes. It shouldn't contain anything that is not necessary to demonstrate the issue. Your question still lacks that, so it is still off-topic.

    – Ulrich Eckhardt
    Jul 24 at 16:31













21












21








21


5






One of my programs is exceeding the time limit when I am using fans = fans + s[i], while when I am using fans += s[i] it is being accepted... Why does this happen?
To Explain more , fans is a string and s is also a string so while iterating over string s i want only some characters of s so i am creating a new string fans.Now there are two ways in which i can add character to my new string fans. The Problem is mentioned below



fans = fans + s[i]; // gives Time limit exceeded 
fans += s[i]; // runs successfully









share|improve this question
















One of my programs is exceeding the time limit when I am using fans = fans + s[i], while when I am using fans += s[i] it is being accepted... Why does this happen?
To Explain more , fans is a string and s is also a string so while iterating over string s i want only some characters of s so i am creating a new string fans.Now there are two ways in which i can add character to my new string fans. The Problem is mentioned below



fans = fans + s[i]; // gives Time limit exceeded 
fans += s[i]; // runs successfully






c++ performance stdstring compound-assignment






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jul 24 at 4:25







Naman

















asked Jul 21 at 10:33









NamanNaman

1361 silver badge12 bronze badges




1361 silver badge12 bronze badges





closed as off-topic by Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton Jul 22 at 14:24


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Reproducible Example." – Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton
If this question can be reworded to fit the rules in the help center, please edit the question.









closed as off-topic by Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton Jul 22 at 14:24


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Reproducible Example." – Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton
If this question can be reworded to fit the rules in the help center, please edit the question.







closed as off-topic by Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton Jul 22 at 14:24


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Reproducible Example." – Ulrich Eckhardt, Daniel Kamil Kozar, Toby Speight, Matthieu M., Rory Daulton
If this question can be reworded to fit the rules in the help center, please edit the question.







  • 1





    One makes a temporary, the other doesn't. Move-assignment can make the former more efficient, but it can't get any better than the later.

    – WhozCraig
    Jul 21 at 10:38







  • 7





    Please extract and provide a minimal reproducible example, your question is off-topic without it. As a new user, also take the tour and read How to Ask.

    – Ulrich Eckhardt
    Jul 21 at 10:43






  • 2





    So fans is an std::string and s[i] is a char? Or is it another string containing a single character?

    – Fabio Turati
    Jul 22 at 1:01






  • 1





    @Naman Have you read Ulrich Eckhardt's comment, and mine? At the very least you should clarify what type fans and s[i] are, but actually it would be better if you edited your question and added a full program (minimal reproducible example) that we can copy and compile. Just check the links that you've been given. It won't take long, and it will improve your question significantly. Thank you!

    – Fabio Turati
    Jul 23 at 0:45






  • 1





    You're not supposed to paste the code of the program you're working on. You are expected to extract a minimal reproducible example from that code and post that. It should be possible to take it and compile it without changes. It shouldn't contain anything that is not necessary to demonstrate the issue. Your question still lacks that, so it is still off-topic.

    – Ulrich Eckhardt
    Jul 24 at 16:31












  • 1





    One makes a temporary, the other doesn't. Move-assignment can make the former more efficient, but it can't get any better than the later.

    – WhozCraig
    Jul 21 at 10:38







  • 7





    Please extract and provide a minimal reproducible example, your question is off-topic without it. As a new user, also take the tour and read How to Ask.

    – Ulrich Eckhardt
    Jul 21 at 10:43






  • 2





    So fans is an std::string and s[i] is a char? Or is it another string containing a single character?

    – Fabio Turati
    Jul 22 at 1:01






  • 1





    @Naman Have you read Ulrich Eckhardt's comment, and mine? At the very least you should clarify what type fans and s[i] are, but actually it would be better if you edited your question and added a full program (minimal reproducible example) that we can copy and compile. Just check the links that you've been given. It won't take long, and it will improve your question significantly. Thank you!

    – Fabio Turati
    Jul 23 at 0:45






  • 1





    You're not supposed to paste the code of the program you're working on. You are expected to extract a minimal reproducible example from that code and post that. It should be possible to take it and compile it without changes. It shouldn't contain anything that is not necessary to demonstrate the issue. Your question still lacks that, so it is still off-topic.

    – Ulrich Eckhardt
    Jul 24 at 16:31







1




1





One makes a temporary, the other doesn't. Move-assignment can make the former more efficient, but it can't get any better than the later.

– WhozCraig
Jul 21 at 10:38






One makes a temporary, the other doesn't. Move-assignment can make the former more efficient, but it can't get any better than the later.

– WhozCraig
Jul 21 at 10:38





7




7





Please extract and provide a minimal reproducible example, your question is off-topic without it. As a new user, also take the tour and read How to Ask.

– Ulrich Eckhardt
Jul 21 at 10:43





Please extract and provide a minimal reproducible example, your question is off-topic without it. As a new user, also take the tour and read How to Ask.

– Ulrich Eckhardt
Jul 21 at 10:43




2




2





So fans is an std::string and s[i] is a char? Or is it another string containing a single character?

– Fabio Turati
Jul 22 at 1:01





So fans is an std::string and s[i] is a char? Or is it another string containing a single character?

– Fabio Turati
Jul 22 at 1:01




1




1





@Naman Have you read Ulrich Eckhardt's comment, and mine? At the very least you should clarify what type fans and s[i] are, but actually it would be better if you edited your question and added a full program (minimal reproducible example) that we can copy and compile. Just check the links that you've been given. It won't take long, and it will improve your question significantly. Thank you!

– Fabio Turati
Jul 23 at 0:45





@Naman Have you read Ulrich Eckhardt's comment, and mine? At the very least you should clarify what type fans and s[i] are, but actually it would be better if you edited your question and added a full program (minimal reproducible example) that we can copy and compile. Just check the links that you've been given. It won't take long, and it will improve your question significantly. Thank you!

– Fabio Turati
Jul 23 at 0:45




1




1





You're not supposed to paste the code of the program you're working on. You are expected to extract a minimal reproducible example from that code and post that. It should be possible to take it and compile it without changes. It shouldn't contain anything that is not necessary to demonstrate the issue. Your question still lacks that, so it is still off-topic.

– Ulrich Eckhardt
Jul 24 at 16:31





You're not supposed to paste the code of the program you're working on. You are expected to extract a minimal reproducible example from that code and post that. It should be possible to take it and compile it without changes. It shouldn't contain anything that is not necessary to demonstrate the issue. Your question still lacks that, so it is still off-topic.

– Ulrich Eckhardt
Jul 24 at 16:31












4 Answers
4






active

oldest

votes


















22














For built-in types a += b is exactly the same as a = a + b, but for classes, those operators are overloaded and call different functions.

In your example fans = fans + s[i] creates a temporary string, and assigns (moves) it to fans, but fans += s[i] does not create that temporary, hence it may be faster.






share|improve this answer




















  • 2





    "+=" may also cause a relocation if the string size is already as big as the preallocated buffer. If later on this turns out to be a problem (of course this should be measured), and if the size may be estimated in advance, the buffer size may be increased explicitly using string::reserve().

    – IMil
    Jul 22 at 2:07











  • @IMil In fact, depending on how the implementation handles allocation, it's quite possible that there's no difference between the two methods, isn't it? With a naive implementation I'd expect that both methods take almost exactly the same time (the time of 1 allocation).

    – MC ΔT
    Jul 22 at 4:21






  • 1





    @MCΔT that's right. So, it would make sense to suggest to the OP that if performance is an issue, one should understand how standard containers work and what they do and don't guarantee in terms of speed and memory. Modifying an std::string inside a tight loop is definitely wasteful, but without knowing context it's hard to suggest replacement.

    – IMil
    Jul 22 at 4:38


















10














std::string has members operator + and operator +=. The former is usually implemented with the latter by way of an intermediate temporary. Effectively looking something like this (check your implementation source if you want to know exactly what yours does):



/// note reference return type
std::string& operator +=(char c)

this->append(c);
return *this;


// note value return type
std::string operator +(char c) const

std::string tmp = *this;
tmp += c; // or just tmp.append(c) directly
return tmp;



The setup of tmp is expensive. The overall function can (and usually is) made better with move-assignment semantics to the final destination on the caller-side, but the expense of the temporary is none-the-less still there. Do it a few times and you won't notice the difference. Do it thousands, or millions, etc. of times, and it can mean a world of difference.






share|improve this answer

























  • Implementing string+anything or string+=anything in terms of the other looks to always be inefficient (one allocation and deallocation too much). Are you sure there are implementations doing that?

    – Deduplicator
    Jul 21 at 20:24












  • @Deduplicator += is usually the more efficient of the two (though there may be outliers). It is relatively common to implement + by calling += as above, and this does not incur any significant overhead. Both operators typically accept their RHS argument by const reference (if it is something non-trivial), so there is no extra copying of that argument, merely plain function call overhead -- and even that will often be eliminated if the compiler inlines it. Similarly NRVO or one of its friends means that operator+ only creates one temporary, not two.

    – Miral
    Jul 22 at 6:49







  • 1





    @Miral Let's go through it, ok? += using +, the string will be newly allocated, using any extra capacity available is impossible. + using +=, the string will allocate for a copy of the lhs, and must then reallocate to accomodate the rhs too. With types where addition is not concatenation one generally doesn't have that problem, but this is about strings featuring a capacity, specifically std::string.

    – Deduplicator
    Jul 22 at 8:51











  • As I said, normally you would not implement += by calling +, because that is completely inefficient. For + calling +=, yes, you're correct that the exact implementation above is not as efficient as it could be, since it might allocate twice (but if the appended rhs fits into the capacity of the lhs, then that won't happen). For efficiency a different implementation would commonly be used in practice which reserves the appended size before calling += (or the moral equivalent). That was outside the scope of this answer, though.

    – Miral
    Jul 22 at 23:47


















9














If you use fans=fans+s[i], the string will be copied in every loop pass. The new element will be added to the copy of the string and the result will be reassigned to the variable fans. After this the old string will have to be removed because it is not referenced anymore. This takes a whole lot of time.



If you use the augmented assignment fans+=s[i] the string will not be copied in every loop pass and there is no need of removing the reference variable as there is no reference variable here. This saves a lot of time.



I hope now you can understand!!






share|improve this answer



























  • In modern C++ there is no need to "copy" the string - move semantics can apply.

    – Alnitak
    Jul 22 at 12:32











  • @Alnitak, I believe move semantics can make string = string + s1 better than without move semantics, but not as good as string += s1. I believe the former will always have at least one allocation and one full copy of all of the bytes of both string and s1, while the latter (string += s1) copies only the bytes of s1 and does not make any extra allocation (as long as the result can fit in the already-allocated capacity of string). Please see my related post [stackoverflow.com/q/57151379/1245420] and if I'm wrong, please correct me!

    – phonetagger
    Jul 22 at 18:21











  • @phonetagger I was alluding to the additional copy caused by the = operator without move semantics available. With move semantics, the result of string + s1 can be reassigned to string without copy overhead. But yes, there'd be a temporary created to make string + s1 in the first place, which does also involve a copy operation.

    – Alnitak
    Jul 23 at 10:08











  • In fans = fans + s[i], the result of operator+ must materialize a temporary object ; which can be moved out of into fans, but this still necessitates a complete copy of the original content of fans existing simultaneously with the original content, until this move happens and then the original content is discarded

    – M.M
    Jul 24 at 4:33



















2














For fundamental types, a = a + b and a += b mean the same thing.



For arbitrary class types, a = a + b and a += b are unrelated; they look up different operators, and those operators can do arbitrary things. Them being actually unrelated is code smell, a sign of a design problem.



a = a + b becomes operator=( a, operator+( a, b ) ) roughly; the actual lookup rules are a bit more complex (involving member operators and non-member operators, and the fact that = doesn't have a non-member operator, etc), but that is the core of it.



a += b becomes operator+=( a, b ) in a similar sense.



Now, it is a common pattern to implement + in terms of +=; if you do this, you get:



a = a + b


becomes



a = ((auto)(a) += b);


where (auto) is the new c++20/c++23 "create a temporary copy of the argument" feature.



Fundamentally, a+=b can reuse the contents of a directly, while a = a + b cannot; at the moment a+b is evaluated, it doesn't know that a will be soon overwritten.



Some libraries deal with this using a technique known as "expression templates"; a+b isn't a value, but rather a compile-time description of the expression a+b, which when assigned to a is actually used to populate a with data. With expression templates, the fundamental issue of a+=b knowing more than a=a+b is eliminated.



Now, for std::string specifically, a+b creates a temporary string object, then a=(a+b) moves that into a (it can reuse the buffer of the temporary string object or the buffer of a, the standard is silent on this matter).



a+=b must reuse any excess capacity in the a buffer. So if you a.reserve(1<<30) (1 billion), a+=b cannot allocate more.






share|improve this answer

























  • Could you link to further discussion of this new (auto) feature?

    – M.M
    Jul 24 at 4:28











  • @m.m not discussion, but a paper: open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0849r1.html

    – Yakk - Adam Nevraumont
    Jul 24 at 10:35












  • Thanks. Probably should allow static_cast<auto>(x) for consistency , i.e. T(x) means static_cast<T>(x) and vice versa for everything else

    – M.M
    Jul 24 at 12:05







  • 1





    @M.M T(x) does not mean static_cast<T>(x), nor vice versa, in general. It does sometimes. And I'd argue that verbosity here is a sin; C++ standard tends to be over verbose in initial versions of things, and we should fight against that tendency.

    – Yakk - Adam Nevraumont
    Jul 24 at 12:34











  • @Yakk-AdamNevraumont Can u help my question is put on hold , I have made the necessary changes than too nothing happened.Even though it has received many upvotes and answers

    – Naman
    Jul 24 at 13:51



















4 Answers
4






active

oldest

votes








4 Answers
4






active

oldest

votes









active

oldest

votes






active

oldest

votes









22














For built-in types a += b is exactly the same as a = a + b, but for classes, those operators are overloaded and call different functions.

In your example fans = fans + s[i] creates a temporary string, and assigns (moves) it to fans, but fans += s[i] does not create that temporary, hence it may be faster.






share|improve this answer




















  • 2





    "+=" may also cause a relocation if the string size is already as big as the preallocated buffer. If later on this turns out to be a problem (of course this should be measured), and if the size may be estimated in advance, the buffer size may be increased explicitly using string::reserve().

    – IMil
    Jul 22 at 2:07











  • @IMil In fact, depending on how the implementation handles allocation, it's quite possible that there's no difference between the two methods, isn't it? With a naive implementation I'd expect that both methods take almost exactly the same time (the time of 1 allocation).

    – MC ΔT
    Jul 22 at 4:21






  • 1





    @MCΔT that's right. So, it would make sense to suggest to the OP that if performance is an issue, one should understand how standard containers work and what they do and don't guarantee in terms of speed and memory. Modifying an std::string inside a tight loop is definitely wasteful, but without knowing context it's hard to suggest replacement.

    – IMil
    Jul 22 at 4:38















22














For built-in types a += b is exactly the same as a = a + b, but for classes, those operators are overloaded and call different functions.

In your example fans = fans + s[i] creates a temporary string, and assigns (moves) it to fans, but fans += s[i] does not create that temporary, hence it may be faster.






share|improve this answer




















  • 2





    "+=" may also cause a relocation if the string size is already as big as the preallocated buffer. If later on this turns out to be a problem (of course this should be measured), and if the size may be estimated in advance, the buffer size may be increased explicitly using string::reserve().

    – IMil
    Jul 22 at 2:07











  • @IMil In fact, depending on how the implementation handles allocation, it's quite possible that there's no difference between the two methods, isn't it? With a naive implementation I'd expect that both methods take almost exactly the same time (the time of 1 allocation).

    – MC ΔT
    Jul 22 at 4:21






  • 1





    @MCΔT that's right. So, it would make sense to suggest to the OP that if performance is an issue, one should understand how standard containers work and what they do and don't guarantee in terms of speed and memory. Modifying an std::string inside a tight loop is definitely wasteful, but without knowing context it's hard to suggest replacement.

    – IMil
    Jul 22 at 4:38













22












22








22







For built-in types a += b is exactly the same as a = a + b, but for classes, those operators are overloaded and call different functions.

In your example fans = fans + s[i] creates a temporary string, and assigns (moves) it to fans, but fans += s[i] does not create that temporary, hence it may be faster.






share|improve this answer













For built-in types a += b is exactly the same as a = a + b, but for classes, those operators are overloaded and call different functions.

In your example fans = fans + s[i] creates a temporary string, and assigns (moves) it to fans, but fans += s[i] does not create that temporary, hence it may be faster.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jul 21 at 10:45









AyxanAyxan

4,2991 gold badge10 silver badges35 bronze badges




4,2991 gold badge10 silver badges35 bronze badges










  • 2





    "+=" may also cause a relocation if the string size is already as big as the preallocated buffer. If later on this turns out to be a problem (of course this should be measured), and if the size may be estimated in advance, the buffer size may be increased explicitly using string::reserve().

    – IMil
    Jul 22 at 2:07











  • @IMil In fact, depending on how the implementation handles allocation, it's quite possible that there's no difference between the two methods, isn't it? With a naive implementation I'd expect that both methods take almost exactly the same time (the time of 1 allocation).

    – MC ΔT
    Jul 22 at 4:21






  • 1





    @MCΔT that's right. So, it would make sense to suggest to the OP that if performance is an issue, one should understand how standard containers work and what they do and don't guarantee in terms of speed and memory. Modifying an std::string inside a tight loop is definitely wasteful, but without knowing context it's hard to suggest replacement.

    – IMil
    Jul 22 at 4:38












  • 2





    "+=" may also cause a relocation if the string size is already as big as the preallocated buffer. If later on this turns out to be a problem (of course this should be measured), and if the size may be estimated in advance, the buffer size may be increased explicitly using string::reserve().

    – IMil
    Jul 22 at 2:07











  • @IMil In fact, depending on how the implementation handles allocation, it's quite possible that there's no difference between the two methods, isn't it? With a naive implementation I'd expect that both methods take almost exactly the same time (the time of 1 allocation).

    – MC ΔT
    Jul 22 at 4:21






  • 1





    @MCΔT that's right. So, it would make sense to suggest to the OP that if performance is an issue, one should understand how standard containers work and what they do and don't guarantee in terms of speed and memory. Modifying an std::string inside a tight loop is definitely wasteful, but without knowing context it's hard to suggest replacement.

    – IMil
    Jul 22 at 4:38







2




2





"+=" may also cause a relocation if the string size is already as big as the preallocated buffer. If later on this turns out to be a problem (of course this should be measured), and if the size may be estimated in advance, the buffer size may be increased explicitly using string::reserve().

– IMil
Jul 22 at 2:07





"+=" may also cause a relocation if the string size is already as big as the preallocated buffer. If later on this turns out to be a problem (of course this should be measured), and if the size may be estimated in advance, the buffer size may be increased explicitly using string::reserve().

– IMil
Jul 22 at 2:07













@IMil In fact, depending on how the implementation handles allocation, it's quite possible that there's no difference between the two methods, isn't it? With a naive implementation I'd expect that both methods take almost exactly the same time (the time of 1 allocation).

– MC ΔT
Jul 22 at 4:21





@IMil In fact, depending on how the implementation handles allocation, it's quite possible that there's no difference between the two methods, isn't it? With a naive implementation I'd expect that both methods take almost exactly the same time (the time of 1 allocation).

– MC ΔT
Jul 22 at 4:21




1




1





@MCΔT that's right. So, it would make sense to suggest to the OP that if performance is an issue, one should understand how standard containers work and what they do and don't guarantee in terms of speed and memory. Modifying an std::string inside a tight loop is definitely wasteful, but without knowing context it's hard to suggest replacement.

– IMil
Jul 22 at 4:38





@MCΔT that's right. So, it would make sense to suggest to the OP that if performance is an issue, one should understand how standard containers work and what they do and don't guarantee in terms of speed and memory. Modifying an std::string inside a tight loop is definitely wasteful, but without knowing context it's hard to suggest replacement.

– IMil
Jul 22 at 4:38













10














std::string has members operator + and operator +=. The former is usually implemented with the latter by way of an intermediate temporary. Effectively looking something like this (check your implementation source if you want to know exactly what yours does):



/// note reference return type
std::string& operator +=(char c)

this->append(c);
return *this;


// note value return type
std::string operator +(char c) const

std::string tmp = *this;
tmp += c; // or just tmp.append(c) directly
return tmp;



The setup of tmp is expensive. The overall function can (and usually is) made better with move-assignment semantics to the final destination on the caller-side, but the expense of the temporary is none-the-less still there. Do it a few times and you won't notice the difference. Do it thousands, or millions, etc. of times, and it can mean a world of difference.






share|improve this answer

























  • Implementing string+anything or string+=anything in terms of the other looks to always be inefficient (one allocation and deallocation too much). Are you sure there are implementations doing that?

    – Deduplicator
    Jul 21 at 20:24












  • @Deduplicator += is usually the more efficient of the two (though there may be outliers). It is relatively common to implement + by calling += as above, and this does not incur any significant overhead. Both operators typically accept their RHS argument by const reference (if it is something non-trivial), so there is no extra copying of that argument, merely plain function call overhead -- and even that will often be eliminated if the compiler inlines it. Similarly NRVO or one of its friends means that operator+ only creates one temporary, not two.

    – Miral
    Jul 22 at 6:49







  • 1





    @Miral Let's go through it, ok? += using +, the string will be newly allocated, using any extra capacity available is impossible. + using +=, the string will allocate for a copy of the lhs, and must then reallocate to accomodate the rhs too. With types where addition is not concatenation one generally doesn't have that problem, but this is about strings featuring a capacity, specifically std::string.

    – Deduplicator
    Jul 22 at 8:51











  • As I said, normally you would not implement += by calling +, because that is completely inefficient. For + calling +=, yes, you're correct that the exact implementation above is not as efficient as it could be, since it might allocate twice (but if the appended rhs fits into the capacity of the lhs, then that won't happen). For efficiency a different implementation would commonly be used in practice which reserves the appended size before calling += (or the moral equivalent). That was outside the scope of this answer, though.

    – Miral
    Jul 22 at 23:47















10














std::string has members operator + and operator +=. The former is usually implemented with the latter by way of an intermediate temporary. Effectively looking something like this (check your implementation source if you want to know exactly what yours does):



/// note reference return type
std::string& operator +=(char c)

this->append(c);
return *this;


// note value return type
std::string operator +(char c) const

std::string tmp = *this;
tmp += c; // or just tmp.append(c) directly
return tmp;



The setup of tmp is expensive. The overall function can (and usually is) made better with move-assignment semantics to the final destination on the caller-side, but the expense of the temporary is none-the-less still there. Do it a few times and you won't notice the difference. Do it thousands, or millions, etc. of times, and it can mean a world of difference.






share|improve this answer

























  • Implementing string+anything or string+=anything in terms of the other looks to always be inefficient (one allocation and deallocation too much). Are you sure there are implementations doing that?

    – Deduplicator
    Jul 21 at 20:24












  • @Deduplicator += is usually the more efficient of the two (though there may be outliers). It is relatively common to implement + by calling += as above, and this does not incur any significant overhead. Both operators typically accept their RHS argument by const reference (if it is something non-trivial), so there is no extra copying of that argument, merely plain function call overhead -- and even that will often be eliminated if the compiler inlines it. Similarly NRVO or one of its friends means that operator+ only creates one temporary, not two.

    – Miral
    Jul 22 at 6:49







  • 1





    @Miral Let's go through it, ok? += using +, the string will be newly allocated, using any extra capacity available is impossible. + using +=, the string will allocate for a copy of the lhs, and must then reallocate to accomodate the rhs too. With types where addition is not concatenation one generally doesn't have that problem, but this is about strings featuring a capacity, specifically std::string.

    – Deduplicator
    Jul 22 at 8:51











  • As I said, normally you would not implement += by calling +, because that is completely inefficient. For + calling +=, yes, you're correct that the exact implementation above is not as efficient as it could be, since it might allocate twice (but if the appended rhs fits into the capacity of the lhs, then that won't happen). For efficiency a different implementation would commonly be used in practice which reserves the appended size before calling += (or the moral equivalent). That was outside the scope of this answer, though.

    – Miral
    Jul 22 at 23:47













10












10








10







std::string has members operator + and operator +=. The former is usually implemented with the latter by way of an intermediate temporary. Effectively looking something like this (check your implementation source if you want to know exactly what yours does):



/// note reference return type
std::string& operator +=(char c)

this->append(c);
return *this;


// note value return type
std::string operator +(char c) const

std::string tmp = *this;
tmp += c; // or just tmp.append(c) directly
return tmp;



The setup of tmp is expensive. The overall function can (and usually is) made better with move-assignment semantics to the final destination on the caller-side, but the expense of the temporary is none-the-less still there. Do it a few times and you won't notice the difference. Do it thousands, or millions, etc. of times, and it can mean a world of difference.






share|improve this answer













std::string has members operator + and operator +=. The former is usually implemented with the latter by way of an intermediate temporary. Effectively looking something like this (check your implementation source if you want to know exactly what yours does):



/// note reference return type
std::string& operator +=(char c)

this->append(c);
return *this;


// note value return type
std::string operator +(char c) const

std::string tmp = *this;
tmp += c; // or just tmp.append(c) directly
return tmp;



The setup of tmp is expensive. The overall function can (and usually is) made better with move-assignment semantics to the final destination on the caller-side, but the expense of the temporary is none-the-less still there. Do it a few times and you won't notice the difference. Do it thousands, or millions, etc. of times, and it can mean a world of difference.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jul 21 at 10:51









WhozCraigWhozCraig

52.9k9 gold badges61 silver badges110 bronze badges




52.9k9 gold badges61 silver badges110 bronze badges















  • Implementing string+anything or string+=anything in terms of the other looks to always be inefficient (one allocation and deallocation too much). Are you sure there are implementations doing that?

    – Deduplicator
    Jul 21 at 20:24












  • @Deduplicator += is usually the more efficient of the two (though there may be outliers). It is relatively common to implement + by calling += as above, and this does not incur any significant overhead. Both operators typically accept their RHS argument by const reference (if it is something non-trivial), so there is no extra copying of that argument, merely plain function call overhead -- and even that will often be eliminated if the compiler inlines it. Similarly NRVO or one of its friends means that operator+ only creates one temporary, not two.

    – Miral
    Jul 22 at 6:49







  • 1





    @Miral Let's go through it, ok? += using +, the string will be newly allocated, using any extra capacity available is impossible. + using +=, the string will allocate for a copy of the lhs, and must then reallocate to accomodate the rhs too. With types where addition is not concatenation one generally doesn't have that problem, but this is about strings featuring a capacity, specifically std::string.

    – Deduplicator
    Jul 22 at 8:51











  • As I said, normally you would not implement += by calling +, because that is completely inefficient. For + calling +=, yes, you're correct that the exact implementation above is not as efficient as it could be, since it might allocate twice (but if the appended rhs fits into the capacity of the lhs, then that won't happen). For efficiency a different implementation would commonly be used in practice which reserves the appended size before calling += (or the moral equivalent). That was outside the scope of this answer, though.

    – Miral
    Jul 22 at 23:47

















  • Implementing string+anything or string+=anything in terms of the other looks to always be inefficient (one allocation and deallocation too much). Are you sure there are implementations doing that?

    – Deduplicator
    Jul 21 at 20:24












  • @Deduplicator += is usually the more efficient of the two (though there may be outliers). It is relatively common to implement + by calling += as above, and this does not incur any significant overhead. Both operators typically accept their RHS argument by const reference (if it is something non-trivial), so there is no extra copying of that argument, merely plain function call overhead -- and even that will often be eliminated if the compiler inlines it. Similarly NRVO or one of its friends means that operator+ only creates one temporary, not two.

    – Miral
    Jul 22 at 6:49







  • 1





    @Miral Let's go through it, ok? += using +, the string will be newly allocated, using any extra capacity available is impossible. + using +=, the string will allocate for a copy of the lhs, and must then reallocate to accomodate the rhs too. With types where addition is not concatenation one generally doesn't have that problem, but this is about strings featuring a capacity, specifically std::string.

    – Deduplicator
    Jul 22 at 8:51











  • As I said, normally you would not implement += by calling +, because that is completely inefficient. For + calling +=, yes, you're correct that the exact implementation above is not as efficient as it could be, since it might allocate twice (but if the appended rhs fits into the capacity of the lhs, then that won't happen). For efficiency a different implementation would commonly be used in practice which reserves the appended size before calling += (or the moral equivalent). That was outside the scope of this answer, though.

    – Miral
    Jul 22 at 23:47
















Implementing string+anything or string+=anything in terms of the other looks to always be inefficient (one allocation and deallocation too much). Are you sure there are implementations doing that?

– Deduplicator
Jul 21 at 20:24






Implementing string+anything or string+=anything in terms of the other looks to always be inefficient (one allocation and deallocation too much). Are you sure there are implementations doing that?

– Deduplicator
Jul 21 at 20:24














@Deduplicator += is usually the more efficient of the two (though there may be outliers). It is relatively common to implement + by calling += as above, and this does not incur any significant overhead. Both operators typically accept their RHS argument by const reference (if it is something non-trivial), so there is no extra copying of that argument, merely plain function call overhead -- and even that will often be eliminated if the compiler inlines it. Similarly NRVO or one of its friends means that operator+ only creates one temporary, not two.

– Miral
Jul 22 at 6:49






@Deduplicator += is usually the more efficient of the two (though there may be outliers). It is relatively common to implement + by calling += as above, and this does not incur any significant overhead. Both operators typically accept their RHS argument by const reference (if it is something non-trivial), so there is no extra copying of that argument, merely plain function call overhead -- and even that will often be eliminated if the compiler inlines it. Similarly NRVO or one of its friends means that operator+ only creates one temporary, not two.

– Miral
Jul 22 at 6:49





1




1





@Miral Let's go through it, ok? += using +, the string will be newly allocated, using any extra capacity available is impossible. + using +=, the string will allocate for a copy of the lhs, and must then reallocate to accomodate the rhs too. With types where addition is not concatenation one generally doesn't have that problem, but this is about strings featuring a capacity, specifically std::string.

– Deduplicator
Jul 22 at 8:51





@Miral Let's go through it, ok? += using +, the string will be newly allocated, using any extra capacity available is impossible. + using +=, the string will allocate for a copy of the lhs, and must then reallocate to accomodate the rhs too. With types where addition is not concatenation one generally doesn't have that problem, but this is about strings featuring a capacity, specifically std::string.

– Deduplicator
Jul 22 at 8:51













As I said, normally you would not implement += by calling +, because that is completely inefficient. For + calling +=, yes, you're correct that the exact implementation above is not as efficient as it could be, since it might allocate twice (but if the appended rhs fits into the capacity of the lhs, then that won't happen). For efficiency a different implementation would commonly be used in practice which reserves the appended size before calling += (or the moral equivalent). That was outside the scope of this answer, though.

– Miral
Jul 22 at 23:47





As I said, normally you would not implement += by calling +, because that is completely inefficient. For + calling +=, yes, you're correct that the exact implementation above is not as efficient as it could be, since it might allocate twice (but if the appended rhs fits into the capacity of the lhs, then that won't happen). For efficiency a different implementation would commonly be used in practice which reserves the appended size before calling += (or the moral equivalent). That was outside the scope of this answer, though.

– Miral
Jul 22 at 23:47











9














If you use fans=fans+s[i], the string will be copied in every loop pass. The new element will be added to the copy of the string and the result will be reassigned to the variable fans. After this the old string will have to be removed because it is not referenced anymore. This takes a whole lot of time.



If you use the augmented assignment fans+=s[i] the string will not be copied in every loop pass and there is no need of removing the reference variable as there is no reference variable here. This saves a lot of time.



I hope now you can understand!!






share|improve this answer



























  • In modern C++ there is no need to "copy" the string - move semantics can apply.

    – Alnitak
    Jul 22 at 12:32











  • @Alnitak, I believe move semantics can make string = string + s1 better than without move semantics, but not as good as string += s1. I believe the former will always have at least one allocation and one full copy of all of the bytes of both string and s1, while the latter (string += s1) copies only the bytes of s1 and does not make any extra allocation (as long as the result can fit in the already-allocated capacity of string). Please see my related post [stackoverflow.com/q/57151379/1245420] and if I'm wrong, please correct me!

    – phonetagger
    Jul 22 at 18:21











  • @phonetagger I was alluding to the additional copy caused by the = operator without move semantics available. With move semantics, the result of string + s1 can be reassigned to string without copy overhead. But yes, there'd be a temporary created to make string + s1 in the first place, which does also involve a copy operation.

    – Alnitak
    Jul 23 at 10:08











  • In fans = fans + s[i], the result of operator+ must materialize a temporary object ; which can be moved out of into fans, but this still necessitates a complete copy of the original content of fans existing simultaneously with the original content, until this move happens and then the original content is discarded

    – M.M
    Jul 24 at 4:33
















9














If you use fans=fans+s[i], the string will be copied in every loop pass. The new element will be added to the copy of the string and the result will be reassigned to the variable fans. After this the old string will have to be removed because it is not referenced anymore. This takes a whole lot of time.



If you use the augmented assignment fans+=s[i] the string will not be copied in every loop pass and there is no need of removing the reference variable as there is no reference variable here. This saves a lot of time.



I hope now you can understand!!






share|improve this answer



























  • In modern C++ there is no need to "copy" the string - move semantics can apply.

    – Alnitak
    Jul 22 at 12:32











  • @Alnitak, I believe move semantics can make string = string + s1 better than without move semantics, but not as good as string += s1. I believe the former will always have at least one allocation and one full copy of all of the bytes of both string and s1, while the latter (string += s1) copies only the bytes of s1 and does not make any extra allocation (as long as the result can fit in the already-allocated capacity of string). Please see my related post [stackoverflow.com/q/57151379/1245420] and if I'm wrong, please correct me!

    – phonetagger
    Jul 22 at 18:21











  • @phonetagger I was alluding to the additional copy caused by the = operator without move semantics available. With move semantics, the result of string + s1 can be reassigned to string without copy overhead. But yes, there'd be a temporary created to make string + s1 in the first place, which does also involve a copy operation.

    – Alnitak
    Jul 23 at 10:08











  • In fans = fans + s[i], the result of operator+ must materialize a temporary object ; which can be moved out of into fans, but this still necessitates a complete copy of the original content of fans existing simultaneously with the original content, until this move happens and then the original content is discarded

    – M.M
    Jul 24 at 4:33














9












9








9







If you use fans=fans+s[i], the string will be copied in every loop pass. The new element will be added to the copy of the string and the result will be reassigned to the variable fans. After this the old string will have to be removed because it is not referenced anymore. This takes a whole lot of time.



If you use the augmented assignment fans+=s[i] the string will not be copied in every loop pass and there is no need of removing the reference variable as there is no reference variable here. This saves a lot of time.



I hope now you can understand!!






share|improve this answer















If you use fans=fans+s[i], the string will be copied in every loop pass. The new element will be added to the copy of the string and the result will be reassigned to the variable fans. After this the old string will have to be removed because it is not referenced anymore. This takes a whole lot of time.



If you use the augmented assignment fans+=s[i] the string will not be copied in every loop pass and there is no need of removing the reference variable as there is no reference variable here. This saves a lot of time.



I hope now you can understand!!







share|improve this answer














share|improve this answer



share|improve this answer








edited Jul 22 at 9:43









yassin

5352 gold badges6 silver badges18 bronze badges




5352 gold badges6 silver badges18 bronze badges










answered Jul 21 at 11:00









Sahil SrivastavSahil Srivastav

871 bronze badge




871 bronze badge















  • In modern C++ there is no need to "copy" the string - move semantics can apply.

    – Alnitak
    Jul 22 at 12:32











  • @Alnitak, I believe move semantics can make string = string + s1 better than without move semantics, but not as good as string += s1. I believe the former will always have at least one allocation and one full copy of all of the bytes of both string and s1, while the latter (string += s1) copies only the bytes of s1 and does not make any extra allocation (as long as the result can fit in the already-allocated capacity of string). Please see my related post [stackoverflow.com/q/57151379/1245420] and if I'm wrong, please correct me!

    – phonetagger
    Jul 22 at 18:21











  • @phonetagger I was alluding to the additional copy caused by the = operator without move semantics available. With move semantics, the result of string + s1 can be reassigned to string without copy overhead. But yes, there'd be a temporary created to make string + s1 in the first place, which does also involve a copy operation.

    – Alnitak
    Jul 23 at 10:08











  • In fans = fans + s[i], the result of operator+ must materialize a temporary object ; which can be moved out of into fans, but this still necessitates a complete copy of the original content of fans existing simultaneously with the original content, until this move happens and then the original content is discarded

    – M.M
    Jul 24 at 4:33


















  • In modern C++ there is no need to "copy" the string - move semantics can apply.

    – Alnitak
    Jul 22 at 12:32











  • @Alnitak, I believe move semantics can make string = string + s1 better than without move semantics, but not as good as string += s1. I believe the former will always have at least one allocation and one full copy of all of the bytes of both string and s1, while the latter (string += s1) copies only the bytes of s1 and does not make any extra allocation (as long as the result can fit in the already-allocated capacity of string). Please see my related post [stackoverflow.com/q/57151379/1245420] and if I'm wrong, please correct me!

    – phonetagger
    Jul 22 at 18:21











  • @phonetagger I was alluding to the additional copy caused by the = operator without move semantics available. With move semantics, the result of string + s1 can be reassigned to string without copy overhead. But yes, there'd be a temporary created to make string + s1 in the first place, which does also involve a copy operation.

    – Alnitak
    Jul 23 at 10:08











  • In fans = fans + s[i], the result of operator+ must materialize a temporary object ; which can be moved out of into fans, but this still necessitates a complete copy of the original content of fans existing simultaneously with the original content, until this move happens and then the original content is discarded

    – M.M
    Jul 24 at 4:33

















In modern C++ there is no need to "copy" the string - move semantics can apply.

– Alnitak
Jul 22 at 12:32





In modern C++ there is no need to "copy" the string - move semantics can apply.

– Alnitak
Jul 22 at 12:32













@Alnitak, I believe move semantics can make string = string + s1 better than without move semantics, but not as good as string += s1. I believe the former will always have at least one allocation and one full copy of all of the bytes of both string and s1, while the latter (string += s1) copies only the bytes of s1 and does not make any extra allocation (as long as the result can fit in the already-allocated capacity of string). Please see my related post [stackoverflow.com/q/57151379/1245420] and if I'm wrong, please correct me!

– phonetagger
Jul 22 at 18:21





@Alnitak, I believe move semantics can make string = string + s1 better than without move semantics, but not as good as string += s1. I believe the former will always have at least one allocation and one full copy of all of the bytes of both string and s1, while the latter (string += s1) copies only the bytes of s1 and does not make any extra allocation (as long as the result can fit in the already-allocated capacity of string). Please see my related post [stackoverflow.com/q/57151379/1245420] and if I'm wrong, please correct me!

– phonetagger
Jul 22 at 18:21













@phonetagger I was alluding to the additional copy caused by the = operator without move semantics available. With move semantics, the result of string + s1 can be reassigned to string without copy overhead. But yes, there'd be a temporary created to make string + s1 in the first place, which does also involve a copy operation.

– Alnitak
Jul 23 at 10:08





@phonetagger I was alluding to the additional copy caused by the = operator without move semantics available. With move semantics, the result of string + s1 can be reassigned to string without copy overhead. But yes, there'd be a temporary created to make string + s1 in the first place, which does also involve a copy operation.

– Alnitak
Jul 23 at 10:08













In fans = fans + s[i], the result of operator+ must materialize a temporary object ; which can be moved out of into fans, but this still necessitates a complete copy of the original content of fans existing simultaneously with the original content, until this move happens and then the original content is discarded

– M.M
Jul 24 at 4:33






In fans = fans + s[i], the result of operator+ must materialize a temporary object ; which can be moved out of into fans, but this still necessitates a complete copy of the original content of fans existing simultaneously with the original content, until this move happens and then the original content is discarded

– M.M
Jul 24 at 4:33












2














For fundamental types, a = a + b and a += b mean the same thing.



For arbitrary class types, a = a + b and a += b are unrelated; they look up different operators, and those operators can do arbitrary things. Them being actually unrelated is code smell, a sign of a design problem.



a = a + b becomes operator=( a, operator+( a, b ) ) roughly; the actual lookup rules are a bit more complex (involving member operators and non-member operators, and the fact that = doesn't have a non-member operator, etc), but that is the core of it.



a += b becomes operator+=( a, b ) in a similar sense.



Now, it is a common pattern to implement + in terms of +=; if you do this, you get:



a = a + b


becomes



a = ((auto)(a) += b);


where (auto) is the new c++20/c++23 "create a temporary copy of the argument" feature.



Fundamentally, a+=b can reuse the contents of a directly, while a = a + b cannot; at the moment a+b is evaluated, it doesn't know that a will be soon overwritten.



Some libraries deal with this using a technique known as "expression templates"; a+b isn't a value, but rather a compile-time description of the expression a+b, which when assigned to a is actually used to populate a with data. With expression templates, the fundamental issue of a+=b knowing more than a=a+b is eliminated.



Now, for std::string specifically, a+b creates a temporary string object, then a=(a+b) moves that into a (it can reuse the buffer of the temporary string object or the buffer of a, the standard is silent on this matter).



a+=b must reuse any excess capacity in the a buffer. So if you a.reserve(1<<30) (1 billion), a+=b cannot allocate more.






share|improve this answer

























  • Could you link to further discussion of this new (auto) feature?

    – M.M
    Jul 24 at 4:28











  • @m.m not discussion, but a paper: open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0849r1.html

    – Yakk - Adam Nevraumont
    Jul 24 at 10:35












  • Thanks. Probably should allow static_cast<auto>(x) for consistency , i.e. T(x) means static_cast<T>(x) and vice versa for everything else

    – M.M
    Jul 24 at 12:05







  • 1





    @M.M T(x) does not mean static_cast<T>(x), nor vice versa, in general. It does sometimes. And I'd argue that verbosity here is a sin; C++ standard tends to be over verbose in initial versions of things, and we should fight against that tendency.

    – Yakk - Adam Nevraumont
    Jul 24 at 12:34











  • @Yakk-AdamNevraumont Can u help my question is put on hold , I have made the necessary changes than too nothing happened.Even though it has received many upvotes and answers

    – Naman
    Jul 24 at 13:51















2














For fundamental types, a = a + b and a += b mean the same thing.



For arbitrary class types, a = a + b and a += b are unrelated; they look up different operators, and those operators can do arbitrary things. Them being actually unrelated is code smell, a sign of a design problem.



a = a + b becomes operator=( a, operator+( a, b ) ) roughly; the actual lookup rules are a bit more complex (involving member operators and non-member operators, and the fact that = doesn't have a non-member operator, etc), but that is the core of it.



a += b becomes operator+=( a, b ) in a similar sense.



Now, it is a common pattern to implement + in terms of +=; if you do this, you get:



a = a + b


becomes



a = ((auto)(a) += b);


where (auto) is the new c++20/c++23 "create a temporary copy of the argument" feature.



Fundamentally, a+=b can reuse the contents of a directly, while a = a + b cannot; at the moment a+b is evaluated, it doesn't know that a will be soon overwritten.



Some libraries deal with this using a technique known as "expression templates"; a+b isn't a value, but rather a compile-time description of the expression a+b, which when assigned to a is actually used to populate a with data. With expression templates, the fundamental issue of a+=b knowing more than a=a+b is eliminated.



Now, for std::string specifically, a+b creates a temporary string object, then a=(a+b) moves that into a (it can reuse the buffer of the temporary string object or the buffer of a, the standard is silent on this matter).



a+=b must reuse any excess capacity in the a buffer. So if you a.reserve(1<<30) (1 billion), a+=b cannot allocate more.






share|improve this answer

























  • Could you link to further discussion of this new (auto) feature?

    – M.M
    Jul 24 at 4:28











  • @m.m not discussion, but a paper: open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0849r1.html

    – Yakk - Adam Nevraumont
    Jul 24 at 10:35












  • Thanks. Probably should allow static_cast<auto>(x) for consistency , i.e. T(x) means static_cast<T>(x) and vice versa for everything else

    – M.M
    Jul 24 at 12:05







  • 1





    @M.M T(x) does not mean static_cast<T>(x), nor vice versa, in general. It does sometimes. And I'd argue that verbosity here is a sin; C++ standard tends to be over verbose in initial versions of things, and we should fight against that tendency.

    – Yakk - Adam Nevraumont
    Jul 24 at 12:34











  • @Yakk-AdamNevraumont Can u help my question is put on hold , I have made the necessary changes than too nothing happened.Even though it has received many upvotes and answers

    – Naman
    Jul 24 at 13:51













2












2








2







For fundamental types, a = a + b and a += b mean the same thing.



For arbitrary class types, a = a + b and a += b are unrelated; they look up different operators, and those operators can do arbitrary things. Them being actually unrelated is code smell, a sign of a design problem.



a = a + b becomes operator=( a, operator+( a, b ) ) roughly; the actual lookup rules are a bit more complex (involving member operators and non-member operators, and the fact that = doesn't have a non-member operator, etc), but that is the core of it.



a += b becomes operator+=( a, b ) in a similar sense.



Now, it is a common pattern to implement + in terms of +=; if you do this, you get:



a = a + b


becomes



a = ((auto)(a) += b);


where (auto) is the new c++20/c++23 "create a temporary copy of the argument" feature.



Fundamentally, a+=b can reuse the contents of a directly, while a = a + b cannot; at the moment a+b is evaluated, it doesn't know that a will be soon overwritten.



Some libraries deal with this using a technique known as "expression templates"; a+b isn't a value, but rather a compile-time description of the expression a+b, which when assigned to a is actually used to populate a with data. With expression templates, the fundamental issue of a+=b knowing more than a=a+b is eliminated.



Now, for std::string specifically, a+b creates a temporary string object, then a=(a+b) moves that into a (it can reuse the buffer of the temporary string object or the buffer of a, the standard is silent on this matter).



a+=b must reuse any excess capacity in the a buffer. So if you a.reserve(1<<30) (1 billion), a+=b cannot allocate more.






share|improve this answer













For fundamental types, a = a + b and a += b mean the same thing.



For arbitrary class types, a = a + b and a += b are unrelated; they look up different operators, and those operators can do arbitrary things. Them being actually unrelated is code smell, a sign of a design problem.



a = a + b becomes operator=( a, operator+( a, b ) ) roughly; the actual lookup rules are a bit more complex (involving member operators and non-member operators, and the fact that = doesn't have a non-member operator, etc), but that is the core of it.



a += b becomes operator+=( a, b ) in a similar sense.



Now, it is a common pattern to implement + in terms of +=; if you do this, you get:



a = a + b


becomes



a = ((auto)(a) += b);


where (auto) is the new c++20/c++23 "create a temporary copy of the argument" feature.



Fundamentally, a+=b can reuse the contents of a directly, while a = a + b cannot; at the moment a+b is evaluated, it doesn't know that a will be soon overwritten.



Some libraries deal with this using a technique known as "expression templates"; a+b isn't a value, but rather a compile-time description of the expression a+b, which when assigned to a is actually used to populate a with data. With expression templates, the fundamental issue of a+=b knowing more than a=a+b is eliminated.



Now, for std::string specifically, a+b creates a temporary string object, then a=(a+b) moves that into a (it can reuse the buffer of the temporary string object or the buffer of a, the standard is silent on this matter).



a+=b must reuse any excess capacity in the a buffer. So if you a.reserve(1<<30) (1 billion), a+=b cannot allocate more.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jul 22 at 13:39









Yakk - Adam NevraumontYakk - Adam Nevraumont

195k21 gold badges214 silver badges404 bronze badges




195k21 gold badges214 silver badges404 bronze badges















  • Could you link to further discussion of this new (auto) feature?

    – M.M
    Jul 24 at 4:28











  • @m.m not discussion, but a paper: open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0849r1.html

    – Yakk - Adam Nevraumont
    Jul 24 at 10:35












  • Thanks. Probably should allow static_cast<auto>(x) for consistency , i.e. T(x) means static_cast<T>(x) and vice versa for everything else

    – M.M
    Jul 24 at 12:05







  • 1





    @M.M T(x) does not mean static_cast<T>(x), nor vice versa, in general. It does sometimes. And I'd argue that verbosity here is a sin; C++ standard tends to be over verbose in initial versions of things, and we should fight against that tendency.

    – Yakk - Adam Nevraumont
    Jul 24 at 12:34











  • @Yakk-AdamNevraumont Can u help my question is put on hold , I have made the necessary changes than too nothing happened.Even though it has received many upvotes and answers

    – Naman
    Jul 24 at 13:51

















  • Could you link to further discussion of this new (auto) feature?

    – M.M
    Jul 24 at 4:28











  • @m.m not discussion, but a paper: open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0849r1.html

    – Yakk - Adam Nevraumont
    Jul 24 at 10:35












  • Thanks. Probably should allow static_cast<auto>(x) for consistency , i.e. T(x) means static_cast<T>(x) and vice versa for everything else

    – M.M
    Jul 24 at 12:05







  • 1





    @M.M T(x) does not mean static_cast<T>(x), nor vice versa, in general. It does sometimes. And I'd argue that verbosity here is a sin; C++ standard tends to be over verbose in initial versions of things, and we should fight against that tendency.

    – Yakk - Adam Nevraumont
    Jul 24 at 12:34











  • @Yakk-AdamNevraumont Can u help my question is put on hold , I have made the necessary changes than too nothing happened.Even though it has received many upvotes and answers

    – Naman
    Jul 24 at 13:51
















Could you link to further discussion of this new (auto) feature?

– M.M
Jul 24 at 4:28





Could you link to further discussion of this new (auto) feature?

– M.M
Jul 24 at 4:28













@m.m not discussion, but a paper: open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0849r1.html

– Yakk - Adam Nevraumont
Jul 24 at 10:35






@m.m not discussion, but a paper: open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0849r1.html

– Yakk - Adam Nevraumont
Jul 24 at 10:35














Thanks. Probably should allow static_cast<auto>(x) for consistency , i.e. T(x) means static_cast<T>(x) and vice versa for everything else

– M.M
Jul 24 at 12:05






Thanks. Probably should allow static_cast<auto>(x) for consistency , i.e. T(x) means static_cast<T>(x) and vice versa for everything else

– M.M
Jul 24 at 12:05





1




1





@M.M T(x) does not mean static_cast<T>(x), nor vice versa, in general. It does sometimes. And I'd argue that verbosity here is a sin; C++ standard tends to be over verbose in initial versions of things, and we should fight against that tendency.

– Yakk - Adam Nevraumont
Jul 24 at 12:34





@M.M T(x) does not mean static_cast<T>(x), nor vice versa, in general. It does sometimes. And I'd argue that verbosity here is a sin; C++ standard tends to be over verbose in initial versions of things, and we should fight against that tendency.

– Yakk - Adam Nevraumont
Jul 24 at 12:34













@Yakk-AdamNevraumont Can u help my question is put on hold , I have made the necessary changes than too nothing happened.Even though it has received many upvotes and answers

– Naman
Jul 24 at 13:51





@Yakk-AdamNevraumont Can u help my question is put on hold , I have made the necessary changes than too nothing happened.Even though it has received many upvotes and answers

– Naman
Jul 24 at 13:51



Popular posts from this blog

Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

Circuit construction for execution of conditional statements using least significant bitHow are two different registers being used as “control”?How exactly is the stated composite state of the two registers being produced using the $R_zz$ controlled rotations?Efficiently performing controlled rotations in HHLWould this quantum algorithm implementation work?How to prepare a superposed states of odd integers from $1$ to $sqrtN$?Why is this implementation of the order finding algorithm not working?Circuit construction for Hamiltonian simulationHow can I invert the least significant bit of a certain term of a superposed state?Implementing an oracleImplementing a controlled sum operation

Magento 2 “No Payment Methods” in Admin New OrderHow to integrate Paypal Express Checkout with the Magento APIMagento 1.5 - Sales > Order > edit order and shipping methods disappearAuto Invoice Check/Money Order Payment methodAdd more simple payment methods?Shipping methods not showingWhat should I do to change payment methods if changing the configuration has no effects?1.9 - No Payment Methods showing upMy Payment Methods not Showing for downloadable/virtual product when checkout?Magento2 API to access internal payment methodHow to call an existing payment methods in the registration form?