C ++ STL: как перебрать вектор, требуя доступа к элементу и его индексу? - PullRequest
2 голосов
/ 25 мая 2010

Мне часто приходится перебирать векторов STL . Пока я делаю это, мне требуется доступ как к элементу * * * * * *, так и к элементу *

. *1007*.

Раньше я делал это как:

typedef std::vector<Foo> FooVec;
typedef FooVec::iterator FooVecIter;

FooVec fooVec;
int index = 0;
for (FooVecIter i = fooVec.begin(); i != fooVec.end(); ++i, ++index)
{
    Foo& foo = *i;
    if (foo.somethingIsTrue()) // True for most elements
        std::cout << index << ": " << foo << std::endl;
}

Обнаружив BOOST_FOREACH , я сократил это до:

typedef std::vector<Foo> FooVec;

FooVec fooVec;
int index = -1;
BOOST_FOREACH( Foo& foo, fooVec )
{
    ++index;
    if (foo.somethingIsTrue()) // True for most elements
        std::cout << index << ": " << foo << std::endl;
}

Есть ли лучший или более элегантный способ перебора векторов STL, когда требуется ссылка на элемент вектора и его индекс?

Я знаю об альтернативе: for (int i = 0; i < fooVec.size(); ++i) Но я продолжаю читать о том, как не рекомендуется перебирать контейнеры STL, подобные этой.

Ответы [ 4 ]

8 голосов
/ 25 мая 2010
for (size_t i = 0; i < vec.size(); i++)
    elem = vec[i];

Векторы - это тонкая обертка над массивами C; используете ли вы итераторы или индексы, это так же быстро. Другие структуры данных не так просты, например, std :: list.

7 голосов
/ 25 мая 2010

Вы всегда можете вычислить индекс в цикле:

std::size_t index = std::distance(fooVec.begin(), i);

Для вектора это, скорее всего, будет реализовано как операция вычитания одного указателя, так что это не особенно дорого.

4 голосов
/ 25 мая 2010

Элегантность в глазах смотрящего, однако помните арифметику указателя / итератора:)

for (FooVecIter i = fooVec.begin(); i != fooVec.end(); ++i)
{
    Foo& foo = *i;
    if (foo.somethingIsTrue()) // True for most elements
        std::cout << i - fooVec.begin() << ": " << foo << std::endl;
}

По сравнению с методом расстояния, вы можете ошибочно сделать это для не-random_access_iterator, поэтому вы всегда будете в O (1) .

3 голосов
/ 25 мая 2010

По конкретному вопросу:

Is there a better or more elegant way to iterate over STL vectors
when both reference to the vector element and its index is required?

ИМХО

for (size_t i = 0; i < fooVec.size(); ++i) {
    Foo & foo = fooVec[i];        // if 'foo' is to be modified
    Foo const& foo = fooVec[i];   // if 'foo' is to be NOT modified
}

- самое простое и элегантное решение. Согласно требованиям вопроса, использование итератора не требуется.

...