Рассмотрим, что работает как ожидалось:
#include <iostream>
struct base
{
virtual ~base(void) {}
virtual void print(std::ostream& pStream) = 0;
};
struct foo : base
{
void print(std::ostream& pStream) { pStream << "foo" << std::endl; }
};
struct bar : base
{
void print(std::ostream& pStream) { pStream << "bar" << std::endl; }
};
#include <boost/bind.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <algorithm>
int main(void)
{
boost::ptr_vector<base> v;
v.push_back(new foo);
v.push_back(new bar);
std::for_each(v.begin(), v.end(),
boost::bind(&base::print, _1, boost::ref(std::cout)));
}
Прежде всего, поскольку вы используете boost, вы также можете использовать ptr_vector
для управления памятью. Итак, это там.
Во-вторых, ваша ошибка в том, что потоки не могут быть скопированы ; однако boost::bind
сделает копию всех своих аргументов при создании функтора. Оберните его в boost::reference_wrapper
(используя служебную функцию boost::ref
), который можно скопировать. Когда придет время, оболочка преобразуется в нужный тип, и вы не заметите разницу.
(Это одна из ситуаций, для которой была создана boost::ref
.)
Несмотря на это, рассмотрите возможность использования BOOST_FOREACH
, который, по моему мнению, генерирует самый чистый код:
#include <boost/foreach.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <algorithm>
#define foreach BOOST_FOREACH
int main(void)
{
boost::ptr_vector<base> v;
v.push_back(new foo);
v.push_back(new bar);
foreach (base* b, v)
{
v->print(std::cout);
}
}