Jir
Jir

Reputation: 3155

Substituting `find_if` function

I wrote a class method using STL find_if. The code is the following:

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

Unfortunately, I later discovered that the machine that will run the code is equipped with the libstdc++ library version 4.1.1-21, which apparently is lacking find_if. Needless to say, I cannot upgrade the library, nor can I ask someone to do it.

When compiling, the error I get is:

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

How can I solve the problem?

I thought I could define a find_if function as described here. However, I have some concerns:

  1. What about performance? The function that makes use of find_if needs to be as efficient as possible.
  2. How can I do conditional compilation? I couldn't find a macro telling the version of the libstdc++ installed.

What are your thoughts about it? TIA, Jir

References

Source files: simulator.h and simulator.cc

Solution

Defined IsJustGreater outside the Simulator class and declared IsJustGreater_s friend of Simulator:

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

Called IsJustGreater in find_if this way: jt = find_if (it, m_eventList.end (), sim::IsJustGreater);

Upvotes: 2

Views: 771

Answers (2)

Dave S
Dave S

Reputation: 21123

From the error, it appears that you're attempting to use an anonymous type as the argument. I do not believe anonymous types are allowed to be template arguments.

From the error, I believe you have something like this:

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

what you want is to give it a name and then change the find_if to instantiate the class (see below)

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() );

Upvotes: 3

Mark Ransom
Mark Ransom

Reputation: 308530

I see that you're using the std:: qualifier before std::list but not std::find_if. Try putting the std:: in front so that the compiler can find it within the namespace.

Upvotes: 1

Related Questions