Boost bind function
I have a abstract base class A and a set of 10 derived classes. The infix operator is overloaded in all of the derived classes
class A{
public:
void printNode( std::ostream& os )
{
this->printNode_p();
}
protected:
virtual void printNode_p( std::ostream& os )
{
os << (*this);
}
};
There is a container which stores the base class pointers. I want to use boost::bind function to call the overloaded infix operator in each of its derived class. I have written like this
std::vector<A*> m_args
....
std::ostream os;
for_each( m_args.begin(), m_args.end(), bind(&A::printNode, _1, os) );
What is the problem with this code? In visual studio i am getting an error like t开发者_开发技巧his
error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
Thanks, Gokul.
Consider this, which works as expected:
#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)));
}
First off, since you're using boost you may as well use ptr_vector
to handle memory management for you. So, that's in there.
Secondly, your error is because streams are not copyable; however, boost::bind
will make a copy of all it's arguments when constructing the functor. Wrap it in a boost::reference_wrapper
(using the boost::ref
utility function), which is copyable. When the time comes, the wrapper will convert to the necessary type and you won't notice the difference.
(This is one of the situations boost::ref
was made for.)
That all said, consider using BOOST_FOREACH
, which in my opinion generates the cleanest code:
#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);
}
}
The problem was that std::ostream is not copyable. I fixed it like this
for_each( m_args.begin(), m_args.end(), bind(&A::printNode, _1, boost::ref(os) ) );
Thanks, Gokul.
精彩评论