Different ways to append two vector in C++ STL

Do not miss this exclusive book on Binary Tree Problems. Get it now for free.

In this article, we have explored Different ways to append two vector in C++ STL which include std::copy, insert, concat, overloaded + operator and other functions.

Table of content

  1. STL vs Standard Library
  2. vector class
  3. Different ways to append using vector class
    • at the beginning of the vector
    • at the end of the vector
    • at a specified index
  4. Other ways
    • std::copy function
    • user defined concat function
    • user defined overload operators + and +=

1. STL vs Standard Library

STL stands from Standard Template Library and as the name suggests it is a library made of generic classes. The syntax to declare one of it is:

template <class local_type_name> class class_name

which means we can declare a class with some generic type members, i.e. a member that we do not know its type from begining. Do not make confusion of the first word class that is used here to symbolize the generic type of the local_type_name that will be used, with the declaration of a class.
It can be used more than one generic type declaration as we can see in the next example:

#include<iostream>
using namespace std;

template <class A, class B> class C
{
    public: A a; B b; // generic type members
    C (A x, B y) {a = x; b = y; } // constructor
    void print() {cout << a << "\n" << b; } // function member
};
int main()
{
    C <int, float> obj_name (3, 3.14);
    obj_name.print();

    return 0;
}

The difference between the two libraies is that the STL works with generic types while the Standard Library works with classes of implicit types. An example of STL class is the vector class and an example of Standard Library might be the string class. Both classes uses almost same behavior the only difference consists in the types that they are manipulate.

2. vector class

We saw earlier how a generic class is defined. Now lets see what is the definition of the vector

template < class T, class Alloc = allocator<T> > class vector;

So, basically a vector has a T generic type aliased as member type vector::value_type and an Alloc type aliased as member type vector::allocator_type.

About T we saw earlier what forms can take, an implicit or a defined type.

What about the Alloc?

This is the type of the allocator object used to define the storage allocation model. By default, the allocator class template is used, which defines the simplest memory allocation model and is value-independent.

To use vector objects we must include the vector header file.

#include <vector>

Some examples declarations:

vector<int> first;
vector<int> second (4,100);                       // four ints with value 100
vector<int> third (second.begin(),second.end());  // iterating through second
vector<int> fourth (third);                       // a copy of third

Notice the use of only one argument in the generic type, the Alloc type is initialiezed by default.

The iterator constructor can also be used to construct from arrays like in the next example:

int v[3] = {1,2,3};
vector<int> fifth ( &*v , &*v+3 );

Notice the addressing of v, which starts from the pointer v and ends at the end of it;

Since & and * are complementary functions the above statement could be simply written:

int v[3] = {1,2,3};
vector<int> fifth ( v , v+3 );

and if we would not know the dimension of v

int v[] = {1,2,3};
vector<int> fifth ( v , v + sizeof(v) / sizeof(int) );

To iterate all the elements of vector fifth we can use the iterator class as shown in the next statement:

vector<int>::iterator i;

for ( i = fifth.begin(); i != fifth.end(); i++ )
    cout<< *i <<" ";

The full code is as fallow

    #include <iostream>
    #include <vector>
    using namespace std;

    int main()
    {
        vector<int> first;
        vector<int> second (4,100);                       
        vector<int> third (second.begin(),second.end());  
        vector<int> fourth (third);                       

        int v[] = {1,2,3};

        vector<int> fifth ( v , v + sizeof(v) / sizeof(int) );

        vector<int>::iterator i;

        for ( i = fifth.begin(); i != fifth.end(); i++ )
            cout<< *i <<" ";

        return 0;
    }

3. Different ways to append

Once we defined some vectors the next thing we can do is to manipulate elements of them. One way is appending method which might be in different cases:

  • at the beginning of the vector

we can use the insert function to insert at the beginning of the fifth vector the forth vector, and for that we need to specify its full dimension

    vector<int>::iterator i;
    i = fifth.begin();
    fifth.insert( i, fourth.begin(), fourth.end() );

Output: 100 100 100 100 1 2 3

  • at the end of the vector

we have two methods here, one is by using the previous examply only, instead to initialize i with the beginning of the fifth we'll initialize it with the end of it

    vector<int>::iterator i;
    i = fifth.end();
    fifth.insert( i, fourth.begin(), fourth.end() );

Output: 1 2 3 100 100 100 100

and the second one is by using the push_back function element by element

    vector<int>::iterator i;
    for ( i = fourth.begin(); i != fourth.end() ; i++ ) 
        fifth.push_back ( *i );

Output: 1 2 3 100 100 100 100

  • at a specified index

we can use the same approach as the beginning insertion only we need to sum with the number of elements after which will wanna make appending and add a condition to check if i is out of scope.

    vector<int>::iterator i;
    i = fifth.begin() + 2;
    if ( *i != NULL )
        fifth.insert( i, fourth.begin(), fourth.end() );

Output: 1 2 100 100 100 100 3

4. Other ways

  • copy function

Definition of the copy function is:

    template <class InputIterator, class OutputIterator>
      OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);

and the next example will do a copy of the fourth elements over the fifth vector:

    copy(fourth.begin() , fourth.end() , back_inserter(fifth) );

Output of the fifth: 1 2 3 100 100 100 100

Here we have used the back_inserter function that onstructs a back-insert iterator that inserts new elements at the end of x. A back-insert iterator is a special type of output iterator designed to allow algorithms that usually overwrite elements to instead insert new elements automatically at the end of the container.

  • user defined concat function

    We can define our own function to implement a concatenation of 2 vectors but it is mandatory to include the vector and algorithm headers
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    template<typename T> void concat( vector<T>& a, vector<T>& b)
        {
         for_each( b.begin(), b.end(), [&](int value){ a.push_back(value); } );
        }

the next call will add the elements of the fourth vector at the end of the fifth vector

    concat( fifth, fourth);

Output of the fifth: 1 2 3 100 100 100 100

  • user defined overload operators + and +=

The most attractive way of writting code in C++ is overloading basic operators.
In this case we can rethink the + and += operators to concatenate two vectors.
The + operator needs an additional vector to store the information while the += operator will append elements to the first one.

implementation for + operator

    template <typename T> vector<T> operator + ( vector<T>& a, vector<T>& b) 
        {
        vector <T> c = a;
        c.insert(c.end(), b.begin(), b.end() );
        return c;  
        }
    fifth = fifth + fourth;

Output of the fifth: 1 2 3 100 100 100 100

implementation for += operator

    template <typename T> vector<T>& operator += ( vector<T>& a, vector<T>& b) 
        {
        a.insert(a.end(), b.begin(), b.end() );
        return a;
        }
    fifth += fourth;

Output of the fifth: 1 2 3 100 100 100 100

A useful hint
A general performance boost for concatenate is to check the size of the vectors and append the one which has the smallest elements to the bigger one.

    if(fourth.size() > fifth.size()) {
        fourth.insert(fourth.end(), fifth.begin(),fifth.end());
    } else {
        fifth.insert(fifth.end(), fourth.begin(),fourth.end());
    }

Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.