Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does std::vector call the swap function when growing? Always or only for some types?

Tags:

c++

vector

swap

As far as I know I can use a vector of vectors (std::vector< std::vector<int> >) and this will be quite efficient, because internally the elements will not be copied, but swapped, which is much faster, because does not include copying of the memory buffers. Am I right?

When does std::vector exactly make use of the swap function? I can't find anything about it in the C++ standard. Does it happen during buffer reallocation?

I did some tests to find it out, but I failed. The swap function for my custom data type isn't called at all.

EDIT: Here is my test program.

like image 730
Michal Czardybon Avatar asked Mar 04 '10 09:03

Michal Czardybon


People also ask

Does swap work on vector C++?

The std::swap() is a built-in function in C++ STL which swaps the value of any two variables passed to it as parameters. The std::vector::swap() function is used to swap the entire contents of one vector with another vector of same type.

How does STD swap work C++?

swap() in C++ The function std::swap() is a built-in function in the C++ Standard Template Library (STL) which swaps the value of two variables. Parameters: The function accepts two mandatory parameters a and b which are to be swapped. The parameters can be of any data type.

Can we use swap in vector?

vector::swap()This function is used to swap the contents of one vector with another vector of same type and sizes of vectors may differ.

Does std::vector always allocate on heap?

std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator). The std::vector class abstracts memory management, as it grows and shrinks automatically if elements are added or removed.


2 Answers

I have no links to back up this claims, but as far as I know, the STL implementation distributed with Microsoft C++ uses some internal non-standard magic annotations to mark vector (and other STL collections) as having-performant-swap so vector<vector<>> won't copy the inner vectors but swap them. Up to VC9 that is, in VC10 they'll switch to rvalue-references. I think you are not supposed to be able to mark your own classes the same way as there's no cross-compiler way to do it and your code will work only on the specific compiler version.

Edit: I had a quick look at the <vector> header in VC9 and found this:

    // vector implements a performant swap
template <class _Ty, class _Ax>
    class _Move_operation_category<vector<_Ty, _Ax> >
    {
    public:
        typedef _Swap_move_tag _Move_cat;
    };

Just for experiment, you could try to specialize this class for you own type, but as I said, this is STL version specific and it's going away in VC10

like image 141
sbk Avatar answered Nov 15 '22 18:11

sbk


std::vector traditionally copy-constructs elements in to the new memory when growing, then the old values are destroyed. However, in the upcoming C++0x with rvalue references and move semantics, std::vector can move-construct elements in to the new memory. This is far more efficient. If you have a vector of strings or some other expensive-to-copy data, then move-constructing them essentially just copies the pointers to the held data and marks the source object as empty. This is very cheap compared to copying and destroying, and effectively solves the costly vector reallocation problem for move-constructable types. It's pretty much the swap optimisation you described, built in to the language.

like image 23
AshleysBrain Avatar answered Nov 15 '22 19:11

AshleysBrain