C ++,find_if不起作用

时间:2010-11-25 15:10:46

标签: c++ std

我在C ++代码中第一次使用std :: find_if函数。我想要执行的示例和逻辑非常简单,但不知怎的,我无法使它工作。

我用这种方式创建了“finder”类:

  /**
  * @class message_by_id_finder
  * @brief A class to find the matching lane wrapper
  */
  class message_by_id_finder
  {
  public:
  /** @brief constructor */
  explicit message_by_id_finder(int id) :
  m_myMessage(id) {
  }

  /** @brief the comparing function */
  bool operator()(const AppMessage& message) const {
  return message.messageId == m_myMessage;
  }

  private:
  /// @brief The id of the searched object
  int m_myMessage;
  };

然后我按照以下方式使用它:

 // Loop messages 
for (vector<AppMessage>::iterator it = messages.begin(); it != messages.end() ; ++it ) {
// Match message with the registered by the App
AppMessage m = *it;
vector<AppMessage>::iterator it2 = find_if(m_messages.begin(), m_messages.end(), message_by_id_finder(m));
if (it2 != m_messages.end()) {
  // FOUND!
} else {
  // NOT FOUND
}
} 

我循环使用m_messages向量,并且有成员匹配id,但it2始终为0x00。我做了一件特别错的事吗?

非常感谢你。

PD:以防万一,其他代码有助于理解问题:

  /**
  * @struct AppMessage
  * @brief Information of a message carrying a result of the App.
  */
  struct AppMessage {
      int messageId;      
      float payloadValue;    
  };

3 个答案:

答案 0 :(得分:2)

你的谓词应该采用迭代类型的对象,在你的情况下是一个AppMessage。

因此,如果你用这样的东西替换你的operator(),我想你会更接近一些工作:

bool operator()(const AppMessage& am) const {
    return am.messageId == m_myMessage;
}

答案 1 :(得分:2)

您必须了解内部find_if的作用才能正确使用它。 cplusplus reference网站提供了一些基本的代码段,可能有助于了解算法实际执行的操作(但请记住,它只是用于教育目的的“伪代码”,而不是实际的实现)。这是本网站提供的std::find_if

的描述
template<class InputIterator, class Predicate>
InputIterator find_if ( InputIterator first, InputIterator last, Predicate pred )
{
  for ( ; first!=last ; first++ ) if ( pred(*first) ) break;
  return first;
}

您可以看到,谓词是为序列中的每个元素调用的。在这里,您有一个std::vector<AppMessage>,因此提供的谓词应该可以使用AppMessage进行调用。

将谓词更改为此应该可以解决问题:

class message_by_id_finder
{
public:
    /** @brief constructor */
    explicit message_by_id_finder(int id) :
        m_myMessage(id)
    {}

    /** @brief the comparing function */
    bool operator()(const AppMessage &appMessage) const {
        return appMessage.messageId == m_myMessage;
    }

private:
    /// @brief The id of the searched object
    const int m_myMessage;
}

另请注意,我制作了operator()m_myMessage const(为什么?因为我可以!)。

答案 2 :(得分:0)

你的布尔逻辑对于find_if是错误的,这很可能导致你的错误。

实际上,如果你的向量不是很短并且你这么做很多次,find和find_if效率非常低,因为它们是线性复杂度。你的使用2个循环,这使得O(M * N),其中M和N是你的集合的长度。

Big-O,正如它所说的那样,是高效编程的主要关键之一。

如果您的集合都已排序,则set_intersect是获取两个集合中所有O(M + N)项的方法。如果不是,您可以对其中一个进行排序,然后您的查找将是O(M log N)或O(N log M),具体取决于您排序的那个。如果一个比另一个长得多,你排序的时间越长,O(M log N)比O(M + N)更有效(典型情况是在数据库表中搜索具有大量记录的几个项目)与少数索引查找相比,即使运行一次表也会效率低下。)