Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofResolved status.

2968. Inconsistencies betweenbasic_string reserve andvector/unordered_map/unordered_set reserve functions

Section: 27.4.3.5[string.capacity]Status:ResolvedSubmitter: Andrew LuoOpened: 2017-05-30Last modified: 2020-09-06

Priority:3

View all otherissues in [string.capacity].

View all issues withResolved status.

Discussion:

According to 27.4.3.5[string.capacity] paragraph 11:

-11-Effects: Afterreserve(),capacity() is greater or equal to the argument ofreserve. [Note: Callingreserve() with ares_arg argument less thancapacity() is in effect a non-binding shrink request. A call withres_arg <= size() is in effect a non-binding shrink-to-fit request. —end note]

A call tobasic_string'sreserve function withres_arg <= size() is taken as a non-binding request to shrink the capacity, whereas forvector (and similarly forunordered_map andunordered_set)according to 23.3.13.3[vector.capacity] p3:

-3-Effects: A directive that informs avector of a planned change in size, so that it can manage the storage allocation accordingly. Afterreserve(),capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value ofcapacity() otherwise. Reallocation happensat this point if and only if the current capacity is less than the argument ofreserve(). If an exceptionis thrown other than by the move constructor of a non-CopyInsertable type, there are no effects.

The problem here is that the different behavior makes it that writing template code where the template argument type is a container type (for examplestd::string orstd::vector<char>) calls toreserve can have different meaning depending on which container type the template is instantiated with. It might be a minor issue but it would be nice to fix the inconsistency. I ran into an issue around this when I was porting code from MSVC++ to G++ (Forbasic_string, MSVC++'s STL implementation, based on Dinkumware, ignores the call ifres_arg < capacity() whereas GCC's STL implementation, libstdc++ will actually shrink the string. For the code I wrote this caused a huge performance issue since we were reallocating the entire string with every call toreserve. Of course we could have worked around it by doing theres_arg < capacity() check ourselves, but I think this inconsistency in the standard isn't desirable).

My proposal is to change 27.4.3.5[string.capacity] paragraph 11 to read:

-11-Effects: Afterreserve(),capacity() is greater or equal to the argument ofreserve if reallocation happens; and equal to the previous value ofcapacity() otherwise. Reallocation happens at this point if and only if the current capacity is less than the argument ofreserve().

I realize that this causes thebasic_string::reserve to no longer have the secondary property of shrinking, but this is whatshrink_to_fit is for.

[2017-07 Toronto Monday issue prioritization]

Priority 3; status to LEWG

[2018-3-17 Resolved byP0966, which was adopted in Jacksonville.]

Proposed resolution:

This wording is relative toN4659.

  1. Edit 27.4.3.5[string.capacity] as indicated:

    void reserve(size_type res_arg=0);

    -10- The member functionreserve() is a directive that informs abasic_string object of a planned changein size, so that it can manage the storage allocation accordingly.

    -11-Effects: Afterreserve(),capacity() is greater or equal to the argument ofreserve,if reallocation happens; and equal to the previous value ofcapacity() otherwise. Reallocation happens at this point if and only if the current capacity is less than the argument ofreserve().[Note: Callingreserve() with ares_arg argument less thancapacity() is in effect a non-binding shrink request. A call withres_arg <= size() is in effect a non-binding shrink-to-fit request. —end note]

    -12-Throws:length_error ifres_arg > max_size().


[8]ページ先頭

©2009-2026 Movatter.jp