Home > OS >  Create const std::vector as the concatenation of two const std::vector
Create const std::vector as the concatenation of two const std::vector

Time:11-09

I would like to create a const std::vector to contain all the elements of two other const std::vector of the same type. Since the vector is const I can not concatenate it step by step with the two const std::vector using the method mentioned in Concatenating two std::vectors.

#include <iostream>
#include <vector>

int main()
{
    const std::vector<int> int_a{0,1};
    const std::vector<int> int_b{2,3};
    const std::vector<int> all_ints;
    
    for (int i: all_ints)
        std::cout << i << ' ';
    return 0;
}

For the example above I would like to define all_ints in a way that the output is 0 1 2 3.

How could that be done?

CodePudding user response:

Make a function that takes the other two vectors, creates a third one, inserts values from the first two, returns the result by value. Then assign this to your const vector:

const std::vector<int> int_a{0,1};
const std::vector<int> int_b{2,3};
const std::vector<int> all_ints = concat(int_a, int_b);

CodePudding user response:

I actually don't know what's the essence of creation of const vectors like this. But a simple hack is to create a temporary non-const vector and fill it with the first two vectors, then create the final const vector. eg:

const std::vector<int> int_a{0,1};
const std::vector<int> int_b{2,3};
std::vector<int> middle(int_a);
middle.insert(middle.begin(),int_b.begin(),int_b.end());
const std::vector<int> all_ints(middle);

As suggested in comments, the last line could be written as:

const std::vector<int> all_ints = std::move(middle);

CodePudding user response:

As already mentioned in @Ayxan Haqverdili's answer, you can create a concatenation function that will be used to initialize your vector.

I propose the following implementation for such a function:

template <template <typename, typename> typename C, typename ... Args>
C<Args...> concat(const C<Args...> & lhs, const C<Args...> & rhs)
{
    C<Args...> res(lhs.cbegin(), lhs.cend());
    res.insert(res.cend(), rhs.cbegin(), rhs.cend());
    return res;
}

Note: This implementation is generalized to all standard library sequence containers except std::array.

Which can then be used like this:

const std::vector<int> a {1, 2, 3};
const std::vector<int> b {4, 5};
    
const std::vector<int> ab = concat(a, b);

Live example here


An alternative, simpler and probably faster version could be:

template <typename C>
C concat(const C & lhs, const C & rhs)
{
    C res(lhs.size()   rhs.size());
    typename C::iterator it = std::copy(lhs.cbegin(), lhs.cend(), res.begin());
    std::copy(rhs.cbegin(), rhs.cend(), it);
    return res;
}

Live example here

  • Related