Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to swap two different vectors in C++, using the std::vector::swap method?

People also ask

Can I swap two vectors?

For two vectors to be swapped, they must be of the same type. The vector class has a member function to swap itself and another vector. The algorithm library has other swap functions with different names and for modified purposes.

Does swap work on vector C++?

It works by swapping the values of objects pointed to by specified iterators. That's all about swap operation on a vector in C++.

Does STD swap work on vectors?

The std::vector::swap function will always swap the contents of vector in constant time. In practice, both the functions will swap the contents of vectors in O(1) time and give the same performance. For consistency, it may be better to use the std::swap.

What does std :: swap do in 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.


Yes, this is perfectly safe to swap vectors of the same type.

Vector under the hood is just a few pointers pointing to the data the vector uses and "end" of the sequence. When you call swap you just exchange those pointers between the vectors. You don't need to worry that the vectors are the same size because of this.

Vectors of different types cannot be swapped using swap. You'd need to implement your own function that does the conversion and swapping.


It is safe because nothing is created during the swap operation. Only data members of the class std::vector are swapped.

Consider the following demonstrative program that makes it clear how objects of the class std::vector are swapped.

#include <iostream>
#include <utility>
#include <iterator>
#include <algorithm>
#include <numeric>

class A
{
public:
    explicit A( size_t n ) : ptr( new int[n]() ), n( n )
    {
        std::iota( ptr, ptr + n, 0 );   
    }

    ~A() 
    { 
        delete []ptr; 
    }

    void swap( A & a ) noexcept
    {
        std::swap( ptr, a.ptr );
        std::swap( n, a.n );
    }

    friend std::ostream & operator <<( std::ostream &os, const A &a )
    {
        std::copy( a.ptr, a.ptr + a.n, std::ostream_iterator<int>( os, " " ) );
        return os;
    }

private:    
    int *ptr;
    size_t n;
};

int main() 
{
    A a1( 10 );
    A a2( 5 );

    std::cout << a1 << '\n';
    std::cout << a2 << '\n';

    std::cout << '\n';

    a1.swap( a2 );

    std::cout << a1 << '\n';
    std::cout << a2 << '\n';

    std::cout << '\n';

    return 0;
}

The program output is

0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 

0 1 2 3 4 
0 1 2 3 4 5 6 7 8 9 

As you see only data members ptr and n are swapped in the member function swap. Neither additional resources are used.

A similar approach is used in the class std::vector.

As for this example

std::vector<Widget> WidgetVector;

std::vector<Widget2> Widget2Vector;

then there are objects of different classes. The member function swap is applied to vectors of the same type.


Is it safe to swap two different vectors in C++, using the std::vector::swap method?

Yes. Swapping can generally be considered safe. On the other hand, safety is subjective and relative and can be considered from different perspectives. As such, it is not possible to give a satisfactory answer without augmenting the question with a context, and choosing what sort of safety is being considered.

Is it still safe to swap the two vectors with the std::vector::swap method: WidgetVector.swap(Widget2Vector); or it will lead to an UB?

There will not be UB. Yes, it is still safe in the sense that the program is ill-formed.


The swap function is defined as follows: void swap( T& a, T& b );. Note here that both a and b are (and have to be) the same type. (There is no such function defined with this signature: void swap( T1& a, T2& b ), as it would make no sense!)

Similarly, the swap() member function of the std::vector class is defined as follows:

template<class T1> class vector // Note: simplified from the ACTUAL STL definition
{
//...
public:
    void swap( vector& other );
//...
};

Now, as there is no 'equivalent' definition with a template override (see Explicit specializations of function templates) for the function parameter (which would be of the form: template <typename T2> void swap(std::vector<T2>& other)), that parameter must be a vector of the same type (template) as the 'calling' class (that is, it must also be a vector<T1>).

Your std::vector<Widget> and std::vector<Widget2> are two different types, so the call to swap won't compile, whether you try to use the member function of either object (as your code does), or using the specialization of the std::swap() function that takes two std:vector objects as parameters.


You can't swap vectors of two different types but it's a compilation error instead of UB. vector::swap only accepts vectors of the same type and allocator.

Not sure if this will work, but if you want a vector containing Widget2s converted from Widgets you can try this:

std::vector<Widget2> Widget2Vector(
    std::make_move_iterator(WidgetVector.begin()),
    std::make_move_iterator(WidgetVector.end())
);

Widget2 will have to be move constructible from Widget.