Graviton
Graviton

Reputation: 83254

One liner to convert from list<T> to vector<T>

Is there an one-liner that converts a list<T> to vector<T>?

A google search returns me a lot of results that use manual, lengthy conversion, which make me puke. Should we go to that much trouble to do something as simple as a list-to-vector conversion?

Upvotes: 73

Views: 53924

Answers (6)

Quanbing Luo
Quanbing Luo

Reputation: 41

I think the one-line convertion in C++23 is simpler and more efficient. For example,

import std;
int main(){
    std::list<std::size_t> l { 1,2,3,4 };
    std::vector<std::size_t> v1 =  std::ranges::to<std::vector>(l);//C++23
    std::vector<std::size_t> v2 = l | std::ranges::to<std::vector>();//C++23
    std::vector<std::size_t> v3(std::from_range, l);//C++23 
}

Upvotes: 1

Barry
Barry

Reputation: 302852

In C++23, the correct answer is:

std::vector<T> = l | std::ranges::to<std::vector>();

This will be more efficient than what I propose below.


The accepted answer of:

std::vector<T> v(std::begin(l), std::end(l));

is certainly correct, but it's (quite unfortunately) not optimal given the recent change in requirement that std::list::size() be O(1). If you have a conforming implementation of std::list (which, for instance, gcc didn't have until 5+), then the following is quite a bit faster (on the order of 50% once we get to 50+ elements):

std::vector<T> v;
v.reserve(l.size());
std::copy(std::begin(l), std::end(l), std::back_inserter(v));

It's not a one liner, but you could always wrap it in one.

Upvotes: 24

A-Sharabiani
A-Sharabiani

Reputation: 19329

Another easy way:

list<int> l {1, 2, 3, 4};
vector<int> v(l.begin(), l.end());

Upvotes: 1

Ulrich Beckert
Ulrich Beckert

Reputation: 59

Although this thread is already old, as "append()" is not available anymore, I wanted to show the newer emplace_back one-liner:

v.emplace_back(l.begin(), l.end());

But this way every element will be re-constructed, so it may not be the fastest solution!

Upvotes: 0

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76788

You can only create a new vector with all the elements from the list:

std::vector<T> v{ std::begin(l), std::end(l) };

where l is a std::list<T>. This will copy all elements from the list to the vector.

Since C++11 this can be made more efficient if you don't need the original list anymore. Instead of copying, you can move all elements into the vector:

std::vector<T> v{ std::make_move_iterator(std::begin(l)), 
                  std::make_move_iterator(std::end(l)) };

Upvotes: 129

Himadri Choudhury
Himadri Choudhury

Reputation: 10353

How about this?

list<T> li;
vector<T> vi;        
copy(li.begin(),li.end(),back_inserter(vi));

Upvotes: 8

Related Questions