Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Pitfalls

Boost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 12. Boost.Foreach

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

В этом разделе описаны некоторые распространенные ошибки с<BOOST_FOREACH>.

Types With Commas

С тех пор<BOOST_FOREACH>это макрос, он должен иметь ровно два аргумента, причем ровно одна запятая разделяет их. Это не всегда удобно, особенно когда тип переменной петли является шаблоном. Подумайте о том, чтобы попробовать<std::map>:

std::map<int,int> m;
// ERROR! Too many arguments to BOOST_FOREACH macro.
BOOST_FOREACH(std::pair<int,int> p, m) // ...

Один из способов исправить это с помощью typedef.

std::map<int,int> m;
typedef std::pair<int,int> pair_t;
BOOST_FOREACH(pair_t p, m) // ...

Другой способ исправить это - предварительно объявить переменную цикла:

std::map<int,int> m;
std::pair<int,int> p;
BOOST_FOREACH(p, m) // ...

Hoisting and Iterator Invalidation

Под крышками<BOOST_FOREACH>используются итераторы для прохождения последовательности элементов. Перед выполнением цикла конечный итератор кэшируется в локальной переменной. Это называетсяподъем, и это важная оптимизация. Однако предполагается, что конечный итератор последовательности стабилен. Обычно это так, но если мы изменяем последовательность, добавляя или удаляя элементы, пока мы повторяем ее, мы можем в конечном итоге подняться на свой собственный горшок.

Рассмотрим следующий код:

std::vector<int> vect(4, 4);
BOOST_FOREACH(int i, vect)
{
    vect.push_back(i + 1);
}

Этот код будет компилироваться, но он имеет неопределенное поведение. Это объясняется тем, что логически это эквивалентно следующему:

std::vector<int> vect(4, 4);
for(std::vector<int>::iterator it1 = vect.begin(), it2 = vect.end();
    it1 != it2; ++it1)
{
    int i = *it1;
    vect.push_back(i + 1); // Oops! This invalidates it1 and it2!
}

Призыв к<vect.push_back()>приведет к тому, что все итераторы в<vect>станут недействительными, включая<it1>и<it2>. Следующая итерация через цикл приведет к использованию недействительных итераторов. Это плохие новости.

Мораль истории состоит в том, чтобы дважды подумать, прежде чем добавлять и удалять элементы из последовательности, над которой вы повторяете. Если это может привести к тому, что итераторы станут недействительными, не делайте этого. Вместо этого используйте обычный<for>цикл.


PrevUpHomeNext

Статья Pitfalls раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 12. Boost.Foreach может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 12. Boost.Foreach ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 17:49:28/0.0065071582794189/0