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;