Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can std::string overload "substr" for rvalue *this and steal resources?

Tags:

It just occurred to me I noticed that std::string's substr operation could be much more efficient for rvalues when it could steal the allocated memory from *this.

The Standard library of N3225 contains the following member function declaration of std::string

basic_string substr(size_type pos = 0, size_type n = npos) const;

Can an implementation that could implement an optimized substr for rvalues overload that and provide two versions, one of which could reuse the buffer for rvalue strings?

basic_string substr(size_type pos = 0) &&;
basic_string substr(size_type pos, size_type n) const;

I imagine the rvalue version could be implemented as follows, reusing the memory of *this an setting *this to a moved-from state.

basic_string substr(size_type pos = 0) && {
  basic_string __r;
  __r.__internal_share_buf(pos, __start + pos, __size - pos);
  __start = 0; // or whatever the 'empty' state is
  return __r;
}

Does this work in an efficient fashion on common string implementations or would this take too much housekeeping?

like image 686
Johannes Schaub - litb Avatar asked Feb 16 '11 21:02

Johannes Schaub - litb


1 Answers

Firstly, an implementation cannot add an overload that steals the source, since that would be detectable:

std::string s="some random string";
std::string s2=std::move(s).substr(5,5);
assert(s=="some random string"); 
assert(s2=="rando");

The first assert would fail if the implementation stole the data from s, and the C++0x wording essentially outlaws copy on write.

Secondly, this wouldn't necessarily be an optimization anyway: you'd have to add additional housekeeping in std::string to handle the case that it's a substring of a larger string, and it would mean keeping large blocks around when there was no longer any strings referencing the large string, just some substring of it.

like image 160
Anthony Williams Avatar answered Sep 27 '22 19:09

Anthony Williams