Как создать вектор, используя определенный диапазон элементов, хранящихся в списке? - PullRequest
1 голос
/ 08 февраля 2012

Я получил list и vector:

list<int> l;
for(int i=0; i<10; i++)
    l.push_back(i);

vector<int> v;

Я хочу инициализировать v, используя первые 5 элементов в l, то есть в данном случае {0,1,2,3,4}.

Кроме петли for в сочетании с v.push_back, есть ли другой способ?memcpy или copy?

PS: В настоящее время я не использую C ++ 0x / C ++ 11.

Ответы [ 4 ]

3 голосов
/ 08 февраля 2012

Вы можете использовать std::copy и std::advance (вместо + для итератора без произвольного доступа):

#include <list>
#include <vector>
#include <iterator>
#include <algorithm>

int main() {
   std::list<int> l;
   for (int i = 0; i < 10; i++)
       l.push_back(i);

   std::vector<int> v;
   v.reserve(5);

   std::list<int>::iterator start = l.begin(), end = start;
   std::advance(end, 5);
   std::copy(start, end, std::back_inserter(v));

   std::cout << v.size();   // 5
}

advance«медленный», однако, из-за природы std::list<>;поэтому op+ недоступен для std::list<>::iterator.

1 голос
/ 08 февраля 2012

Это должно сделать:

#include <list>
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>

struct convF
{
    convF( std::list<int>::const_iterator it_):it(it_){}

    int operator()()
    {
        return *it++;
    }

    std::list<int>::const_iterator it;
};

int main()
{
    std::list<int> l;
    std::vector<int> v;

    l.push_back(5);
    l.push_back(4);
    l.push_back(3);
    l.push_back(2);
    l.push_back(1);
    l.push_back(9);
    l.push_back(11);
    l.push_back(13);
    l.push_back(15);
    l.push_back(16);

    std::generate_n( std::back_inserter( v ), 5, convF(l.begin()) );

    std::copy( v.begin(), v.end(), std::ostream_iterator<int> (std::cout, " "));
    std::cout<<std::endl;
}
1 голос
/ 08 февраля 2012

Вы не можете избежать зацикливания, такова природа списка.Конечно, нет никаких гарантий относительно того, как хранятся данные, поэтому вы не можете использовать что-то вроде memcpy.Если вы не хотите получать доступ к элементам контейнера, проходя через них, вам не следует использовать список.

Как указывалось в других ответах, существует несколько компактных способов использования итераторов.чтобы сделать это, но все они в конечном итоге будут проходить по вашему списку.

0 голосов
/ 08 февраля 2012

самое простое решение:

list<int> l;
for(int i=0; i<10; i++)
    l.push_back(i);

vector<int> v(l.begin(), l.begin()+5);

Этот конструктор использует два итератора, отмечающих начало и один элемент после конца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...