Why has the std::vector::resize signature been changed in C++11?

后端 未结 2 1968
天涯浪人
天涯浪人 2020-12-17 07:45

What are the reasons behind the change in std::vector::resize from the pre-C++11:

void resize( size_type count, T value = T() );
2条回答
  •  情书的邮戳
    2020-12-17 08:10

    One reason is that default arguments are always passed, i.e. copied in this case. Doing

     my_vector.resize(1000000) 
    

    would copy 1 million T objects.

    In C++11 you now have a choice between copying a user-provided value or default-inserting (i.e. constructing) elements in-place, using the std::allocator_traits::construct() function. This allows resizing of vector with elements that are CopyInsertable but not Copyable.

    Note that this change has been done to all sequence containers having a resize() member (vector, deque, forward_list and list), but not for std::string which didn't have a default value argument to begin with.

    Update: apart from the Annex to the current Standard cited by @AndyProwl, the original defect report by @HowardHinnant also clarifies:

    The problem with passing T by value is that it can be significantly more expensive than passing by reference. The converse is also true, however when it is true it is usually far less dramatic (e.g. for scalar types).

    Even with move semantics available, passing this parameter by value can be expensive. Consider for example vector>:

    std::vector x(1000); std::vector> v; ...
    v.resize(v.size()+1, x); 
    

    In the pass-by-value case, x is copied once to the parameter of resize. And then internally, since the code can not know at compile time by how much resize is growing the vector, x is usually copied (not moved) a second time from resize's parameter into its proper place within the vector.

    With pass-by-const-reference, the x in the above example need be copied only once. In this case, x has an expensive copy constructor and so any copies that can be saved represents a significant savings.

    If we can be efficient for push_back, we should be efficient for resize as well. The resize taking a reference parameter has been coded and shipped in the CodeWarrior library with no reports of problems which I am aware of.

提交回复
热议问题