2011-08-02 70 views
2

我寫了一個使用STL find_if的類方法。代碼如下:代替`find_if`函數

void 
Simulator::CommunicateEvent (pEvent e) 
{ 
    pwEvent we (e); 
    std::list<pEvent> l; 

    for (uint32_t i = 0; i < m_simulatorObjects.size(); i++) 
    { 
    l = m_simulatorObjects[i]->ProcessEvent (we); 
    // no action needed if list is empty 
    if (l.empty()) 
     continue; 
    // sorting needed if list comprises 2+ events 
    if (l.size() != 1) 
     l.sort (Event::Compare); 

    std::list<pEvent>::iterator it = m_eventList.begin(); 
    std::list<pEvent>::iterator jt; 
    for (std::list<pEvent>::iterator returnedElementIt = l.begin(); 
     returnedElementIt != l.end(); 
     returnedElementIt++) 
    { 
     // loop through the array until you find an element whose time is just 
     // greater than the time of the element we want to insert 
     Simulator::m_eventTime = (*returnedElementIt)->GetTime(); 
     jt = find_if (it, 
        m_eventList.end(), 
        IsJustGreater); 
     m_eventList.insert (jt, *returnedElementIt); 
     it = jt; 
    } 
    } 
} 

不幸的是,我後來發現,將運行代碼的機器配備了的libstdC++庫版本4.1.1-21,這顯然是缺乏find_if。不用說,我不能升級圖書館,我也不能要求某人這樣做。

編譯時,我得到的錯誤是:

simulator.cc: In member function ‘void sim::Simulator::CommunicateEvent(sim::pEvent)’: 
simulator.cc:168: error: no matching function for call to ‘find_if(std::_List_iterator<boost::shared_ptr<sim::Event> >&, std::_List_iterator<boost::shared_ptr<sim::Event> >, sim::Simulator::<anonymous struct>&)’ 
simulator.cc: In static member function ‘static void sim::Simulator::InsertEvent(sim::pEvent)’: 
simulator.cc:191: error: no matching function for call to ‘find_if(std::_List_iterator<boost::shared_ptr<sim::Event> >&, std::_List_iterator<boost::shared_ptr<sim::Event> >, sim::Simulator::<anonymous struct>&)’ 
make: *** [simulator.o] Error 1 

我怎樣才能解決這個問題?

我想我可以定義一個find_if函數,如here所述。然而,我有一些擔憂:

  1. 性能怎麼樣?使用find_if的函數需要儘可能高效。
  2. 我該如何做條件編譯?我無法找到一個告訴安裝的libstdC++版本的宏。

您對此有何看法? TIA, JIR

參考

源文件:​​和simulator.cc

解決方案

定義IsJustGreaterSimulator類外,並宣佈IsJustGreater_s朋友Simulator

struct IsJustGreater_s : public std::unary_function<const pEvent, bool> { 
    inline bool operator() (const pEvent e1) {return (e1->GetTime() > Simulator::m_eventTime);} 
} IsJustGreater; 

IsJustGreaterfind_if這樣: jt = find_if(it,m_eventList.end(),sim :: IsJustGreater);

+0

IIRC find_if不在C++標準中,僅在C++ 0x草案中。 –

+1

@Alexandre C:'find_if'在C++ 98中,你可能在考慮'copy_if' – Cubbi

+2

你可以發佈一個不爲你編譯的示例程序嗎?鑑於它不完全是一個新模板,所以'std :: find_if'應該在4.1.1中。 –

回答

3

從錯誤中看來,您嘗試使用匿名類型作爲參數。我不相信匿名類型可以作爲模板參數。

從錯誤中,我相信你有這樣的事情:

class Simulator { 
    struct { 
     bool operator(const pEvent& p) { ... } ; 
    } IsJustGreater; 
} 

你想要的是給它一個名稱,然後更改find​​_if實例化的類(見下文)

class Simulator { 
    // class is now an inner named-class 
    struct IsJustGreater { 
     bool operator(const pEvent& p) { ... } ; 
    }; 
} 


// This is how you use the class 
jt = std::find_if(it, m_eventList.end(), IsJustGreater()); 
+0

我想你明白了。 –

+0

好消息。編譯器在使用'find_if'這個靜態函數的兩個函數中的一箇中抱怨'struct sim :: Simulator :: IsJustGreater'的無效使用。現在我想知道如何使這樣的結構靜態。 – Jir

+0

你確定你還沒有試圖使用類成員與實例化一個新的IsJustGreater()嗎? –

1

我看到您在std::list之前使用std::限定符,但不是std::find_if。嘗試將std::放在前面,以便編譯器可以在名稱空間內找到它。

+0

剛剛嘗試過,沒有運氣,但值得一試:) – Jir

+0

我認爲ADL應該從參數中選擇命名空間。 –