Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize std::vector from C-style array?

People also ask

What is the correct way to initialize vector in C++?

Begin Declare v of vector type. Call push_back() function to insert values into vector v. Print “Vector elements:”. for (int a : v) print all the elements of variable a.

Can we create vector from array?

To convert an array to vector, you can use the constructor of Vector, or use a looping statement to add each element of array to vector using push_back() function.

Does std :: array initialize?

std::array contains a built-in array, which can be initialized via an initializer list, which is what the inner set is. The outer set is for aggregate initialization.


Don't forget that you can treat pointers as iterators:

w_.assign(w, w + len);

You use the word initialize so it's unclear if this is one-time assignment or can happen multiple times.

If you just need a one time initialization, you can put it in the constructor and use the two iterator vector constructor:

Foo::Foo(double* w, int len) : w_(w, w + len) { }

Otherwise use assign as previously suggested:

void set_data(double* w, int len)
{
    w_.assign(w, w + len);
}

Well, Pavel was close, but there's even a more simple and elegant solution to initialize a sequential container from a c style array.

In your case:

w_ (array, std::end(array))
  • array will get us a pointer to the beginning of the array (didn't catch it's name),
  • std::end(array) will get us an iterator to the end of the array.

You can 'learn' the size of the array automatically:

template<typename T, size_t N>
void set_data(const T (&w)[N]){
    w_.assign(w, w+N);
}

Hopefully, you can change the interface to set_data as above. It still accepts a C-style array as its first argument. It just happens to take it by reference.


How it works

[ Update: See here for a more comprehensive discussion on learning the size ]

Here is a more general solution:

template<typename T, size_t N>
void copy_from_array(vector<T> &target_vector, const T (&source_array)[N]) {
    target_vector.assign(source_array, source_array+N);
}

This works because the array is being passed as a reference-to-an-array. In C/C++, you cannot pass an array as a function, instead it will decay to a pointer and you lose the size. But in C++, you can pass a reference to the array.

Passing an array by reference requires the types to match up exactly. The size of an array is part of its type. This means we can use the template parameter N to learn the size for us.

It might be even simpler to have this function which returns a vector. With appropriate compiler optimizations in effect, this should be faster than it looks.

template<typename T, size_t N>
vector<T> convert_array_to_vector(const T (&source_array)[N]) {
    return vector<T>(source_array, source_array+N);
}

The quick generic answer:

std::vector<double> vec(carray,carray+carray_size); 

or question specific:

std::vector<double> w_(w,w+len); 

based on above: Don't forget that you can treat pointers as iterators