struct test { int field1; test( int v ) : field1( v ) {} }; typedef boost::shared_ptr<test> test_ptr_t; typedef std::vector<test_ptr_t> test_t; test_t test_array; int main() { test_array.push_back( test_ptr_t( new test(1) ) ); test_array.push_back( test_ptr_t( new test(5) ) ); test_array.push_back( test_ptr_t( new test(10) ) ); typedef boost::indirect_iterator<test_t::const_iterator> test_const_iterator; using boost::make_indirect_iterator; for ( test_const_iterator it = make_indirect_iterator( test_array.begin() ); it != make_indirect_iterator( test_array.end() ); ++it ) { // пишем it->field1 вместо (*it)->field1 std::cout << it->field1 << std::endl; } }
Писанины многовато, но иногда оно того стоит. В алгоритамах indirect_iterator упрощает написание функторов:
test_const_iterator f = std::find_if( make_indirect_iterator( test_array.begin() ), make_indirect_iterator( test_array.end() ), boost::bind( &test::field1, _1 ) == 5 ); std::cout << f->field1 << std::endl;
Стоит отметить, что счастливые пользователи компиляторов с поддержкой нового стандарта(например, GNU C++ 4.5 или MSVC++ 2010) могут заменить все это ситаксическое безобразие лямбда функциями и написать следующее:
auto x = std::find_if( test_array.begin(), test_array.end(), [](test_ptr_t v) { return v->field1 == 5; } ); std::cout << (*x)->field1 << std::endl;