提升绑定功能

时间:2010-04-06 02:03:41

标签: c++ boost bind

我有一个抽象基类A和一组10个派生类。中缀运算符在所有派生类中重载

class A{
 public:
    void printNode( std::ostream& os )
    {
           this->printNode_p();
    } 
  protected:
    virtual void printNode_p( std::ostream& os )
    {
           os << (*this);
    }
};

有一个存储基类指针的容器。我想使用boost :: bind函数在每个派生类中调用重载的中缀运算符。我写得像这样

std::vector<A*> m_args
....
std::ostream os;
for_each( m_args.begin(), m_args.end(), bind(&A::printNode, _1, os) );

此代码有什么问题?在visual studio中我收到这样的错误

  

错误C2248:   '的std :: basic_ios&LT; _Elem,_Traits&GT; :: basic_ios'   :无法访问私人会员   在课堂上宣布   '的std :: basic_ios&LT; _Elem,_Traits&GT;'

谢谢, 戈库尔。

2 个答案:

答案 0 :(得分:5)

考虑一下,它按预期工作:

#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);
    }
}

答案 1 :(得分:0)

问题是std :: ostream不可复制。我修好了这个

for_each( m_args.begin(), m_args.end(), bind(&A::printNode, _1, boost::ref(os) ) );

谢谢, 戈库尔。