3

Imagine this little simplified code snip:

ostringstream os; 
os << "hello world!";           

string str = os.str().c_str();  // copy of os

list<string> lst;
lst.push_back(str);             // copy of str

In WideString there is a function called detach() which gives the responsibility to the called function to handle the mem-allocations.

Is there such a simlar trick for string type?

  • 3
    [Move](http://stackoverflow.com/q/3106110/1171191) [semantics](http://thbecker.net/articles/rvalue_references/section_01.html). `os.str().c_str()` is a pessimisation that stops the compiler doing the right thing in the first place. – BoBTFish Jan 15 '16 at 08:57
  • How about `std::shared_ptr>` if you care about copying that much? – Violet Giraffe Jan 15 '16 at 08:57
  • 5
    Because you're copying copying copying them. – user207421 Jan 15 '16 at 08:59
  • 1
    There's no way to detach the string from an `ostringstream`. Stringstreams trade performance for a convenient/safe interface. The most efficient rewrite of your code would be `lst.emplace_back("hello world!");` – M.M Jan 15 '16 at 09:28

2 Answers2

8

If you can use C++11 you can just use move. You can read about move semantics here: What are move semantics?

lst.push_back(std::move(str)); // str is moved

But here:

string str = os.str().c_str();

you construct new string from const char* returned from c_str, just remove c_str and then C++11 compiler will call move constructor, instead of new string construction.

Community
  • 1
  • 1
ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • 1
    `string str = os.str();` will just "do the right thing" anyway. – BoBTFish Jan 15 '16 at 08:58
  • @ForEveR, what is the difference between "move" and "copy" apart that str is empty. –  Jan 15 '16 at 09:05
  • @NECIPS Primarily that `move()` doesn't create a copy. – πάντα ῥεῖ Jan 15 '16 at 09:07
  • Note that there is still a superfluous copy, and there's nothing you can do about it with `ostringstream` because it returns its internal string by value, and gives you no way to move it out. – Benjamin Lindley Jan 15 '16 at 09:11
  • Sorry, my mind is today a little bit slow... What do you mean with "create a copy"? Moving is for me the same as copying from one buffer to another one. But I think about pointer bending. –  Jan 15 '16 at 09:12
  • @NECIPS Moving steals the internals of the original `string`, so avoids allocating memory for, and copying across, the actual character values. – BoBTFish Jan 15 '16 at 09:13
  • @NECIPS Moving is *not* the same as copying. Briefly, `std::string a = std::move(b);` will make `a` "steal" the internal buffer of `b`. It's a pointer copy, not copying of contents. – Angew is no longer proud of SO Jan 15 '16 at 09:14
0

In Qt library there's different copy on write approach. For example:

QString a = "Hello";   // Create string
QString b = a;         // No copy, `b` has pointer to `a`
a += " world!";        // `b` is copied here, because `a` was modified

Regarding std::string the C++11 tries to solve this with move semantics. Another question could be if it's good idea to handle memory management in containers like QString.

Lukáš Bednařík
  • 2,578
  • 2
  • 15
  • 30