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