2010-11-25 90 views
0

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

我所创建的“取景器”类是这样的:

/** 
    * @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成员但是它始终是0x00。我在做什么特别错误?

非常感谢您提前。

PD:以防万一,另一片了解问题有用代码:

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

您的`operator()`实现是反模式。代码应该写成`return id = m_myMessage;`代替。 **从不**写`如果(条件)返回true;否则返回false;`。 – 2010-11-25 15:22:30

+1

operator()`缺少一个大括号。 `it2!= m_messages.end()`表示发现了消息id *,而不是它。我建议你写一个完整的程序,编译和展示你感到惊讶的行为,然后提出关于该程序的问题。否则,你可能只是整天得到有关拼写错误的答案,其中没有一个出现在你的真实代码中。 – 2010-11-25 15:27:37

+0

谢谢康拉德。但是,不使用你提到的模式会导致错误?除此之外是'return id = m_myMessage;'正确?不应该是'返回ID == m_myMessage;'? – Julen 2010-11-25 15:27:59

回答

2

你的谓语应该遍历该类型的对象,这是你的情况的AppMessage。

所以,如果你是这样的替换您的运营商(),我想你会得到更接近一些工作:

bool operator()(const AppMessage& am) const { 
    return am.messageId == m_myMessage; 
} 
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常量(为什么,因为我可以吗?!)。

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)更有效率(典型情况是在数据库表中搜索有很多记录的几个项目即使一次运行表格也会效率低下,与少数索引查找相比)。