2011-08-02 69 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应该从参数中选择命名空间。 –