2010-04-06 77 views
3

我有一个抽象基类A和一组10个派生类。中缀运算符在所有派生类中都是超载的Boost绑定函数

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 < _Elem,_Traits> :: basic_ios' :不能访问类 “的std :: basic_ios声明私有成员 < _Elem,_Traits>'

谢谢, Gokul。

+0

你有什么问题呢?它不是在编译,还是不在做你想要的? – 2010-04-06 02:08:33

+0

@Alex:我更新了错误 – Gokul 2010-04-06 02:12:01

回答

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); 
    } 
} 
+0

的帖子谢谢....我会查看boost :: ptr_vector – Gokul 2010-04-06 02:25:22

0

问题那std :: ostream是不可复制的。我是这样修复的

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

谢谢, Gokul。