Использование std :: vector <boost :: function> с boost :: bind - PullRequest
2 голосов
/ 03 октября 2011

Пытаясь освоиться с boost, столкнулся с проблемой использования boost::function вместе с std::vector.Я пытаюсь сделать простую вещь: иметь список функций с сигнатурами similair, а затем использовать все эти функции с std::for_each в данных примера.Вот код:

typedef boost::function<int (const char*)> text_processor;
typedef std::vector<text_processor> text_processors;
text_processors processors;
processors.push_back(std::atoi);
processors.push_back(std::strlen);

const char data[] = "123";

std::for_each(processors.begin(), processors.end(),
    std::cout << boost::bind(&text_processors::value_type::operator(), _1, data) 
              << "\n"
);

Итак, с for_each я пытаюсь записать в стандартный вывод результат применения каждой функции к образцу данных.Но это не скомпилируется так (какое-то длинное сообщение о пропущенном операторе << для bind результата).

Если я удалю потоковые операторы, у меня будет скомпилированный, но бесполезный код.Хитрость заключается в том, что я хочу сделать применение функции и вывод текста в одном for_each.Что мне не хватает?Думаю, что с лямбдами или чем-то подобным все будет просто, но не могу найти правильного решения.

1 Ответ

4 голосов
/ 03 октября 2011

Проблема с вашим кодом заключается в том, что вы пытаетесь создать функтор на месте таким образом, который недопустим (вы не можете просто бросить код на третий аргумент for_each, вам нужно передать функтор ).

Без поддержки лямбды в компиляторе вы можете использовать std::transform вместо std::for_each (не проверено ... но это должно работать):

std::transform( processors.begin(), processors.end(),
                std::ostream_iterator<int>( std::cout, "\n" ),
                bind( &text_processors::value_type::operator(), _1, data ) );

Если ваш компилятор поддерживает лямбды, вы можете сделать с ним:

const char data[] = "123";
std::for_each(processors.begin(), processors.end(),
    [&data]( text_processors const & ) { 
        std::cout << boost::bind(&text_processors::value_type::operator(), _1, data) 
              << "\n"
    }
);

Но тогда вы можете вообще избежать bind:

std::for_each( processors.begin(), processors.end(),
               [&data]( text_processors::value_type & op ) {
                   std::cout << op( data ) << "\n";
               }
);
...