2010-04-06 96 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。