Count reference std :: string

I am looking at the code for basic_string (bundled with g ++ 4.2.1). The copy constructor uses the grab() function to "capture" a copy of the string (increase its number of links):

 _CharT* _M_grab( const _Alloc& __alloc1, const _Alloc& __alloc2 ) { return (!_M_is_leaked() && __alloc1 == __alloc2) ? _M_refcopy() : _M_clone(__alloc1); } 

This increases the reference count only if the allocators for the two rows are the same - it makes sense. However, the copy constructor:

 basic_string(const basic_string& __str) : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), __str.get_allocator()), __str.get_allocator()) { } 

The first allocator that passed _M_grab() is a copy of the second. What for? The only way that operator==() for allocator could return false is if the user uses a custom allocator. However, even if this is true, you might think that the copied spreader will equal its original, right? So:

  • Why compare valves in general?
  • Why copy-build a dispenser and compare the copy with the original?
  • What is an example of use when comparing a copy with its original will return false?

Update

Yes, _M_grab() used elsewhere: for assignment. In this case, the allocators passed to _M_grab() are different. Good. But there is still no reason for copying or comparing allocators in the constructor for string .

+4
source share
2 answers

I know zip about the reasoning of the GCC team, but here are my assumptions:

  • For debugging? Distributors MUST be the same.

  • So can he reuse _M_grab ()?

  • Should never be?

+1
source
  • Distributors compare the same values ​​if objects selected from one can be freed along with the other. If this is the case, then two lines may use a link to the same allocator; otherwise everyone needs their own dispenser.

  • The comparison takes place inside _M_grab , which does not know that one argument was constructed from the copies of another argument in this particular case. _M_grab also called from assign , where two lines can have different allocators.

  • The distributor should always compare it with the copy itself.

Update

But there is still no reason for either copying or comparing allocators in the constructor for the string.

There is also no particular reason for implementing two almost identical versions of _M_grab() to avoid unnecessary comparisons that (for most distributors) will happen at compile time. Maybe you think that such micro-optimization would be desirable; apparently, the author of this code did not.

+1
source

All Articles