14 września 2012

Boost.Foreach

Często w książkach można spotkać konstrukcję pętli for, której zadaniem jest prze-iterowanie po jakimś kontenerze. Wtedy warunek zakończenia pętli wygląda najczęściej tak:
it != v.end()
Jeżeli jednak nasz kod z pętli nie usuwa, dodaje, przemieszcza (?) obiektów w kontenerze, można pokusić się o bardziej optymalne rozwiązanie, bowiem metoda end(), będzie wołana na początku każdego rozpoczęcia pętli.
#include <iostream>
#include <vector>
#include <boost/foreach.hpp>

template <typename T>
class Vec : public std::vector<T>
{
public:
    typename std::vector<T>::iterator begin()
    {
        std::cout << "begin()" << std::endl;
        return std::vector<T>::begin();
    }
    typename std::vector<T>::iterator end()
    {
        std::cout << "end()" << std::endl;
        return std::vector<T>::end();
    }
};

int main()
{
    Vec<int> v;
    v.push_back(10);
    v.push_back(45);
    v.push_back(6);

    for (Vec<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        std::cout << "value: " << *it << std::endl;
    }

    return 0;
}
Wynik
begin()
end()
value: 10
end()
value: 45
end()
value: 6
end()
Wypadało by więc, zapisać sobie na boku wartość zwracaną przez end i z takiej wartości korzystać podczas sprawdzania warunku końca pętli. Minus - kod strasznie puchnie - rozwiązanie BOOST_FOREACH()
int main()
{
    Vec<int> v;
    v.push_back(10);
    v.push_back(45);
    v.push_back(6);

    BOOST_FOREACH(int i, v)
    {
        std::cout << "value " << i << std::endl;
    }

    return 0;
}

A oto wynik - z jednym wołaniem metody end()
begin()
end()
value 10
value 45
value 6

Brak komentarzy:

Prześlij komentarz