C++,find_if 不工作
我第一次在 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;
};
I am using for the first time std::find_if function in C++ code. The examples and the logic I want to execute are pretty simple but somehow I cannot make it work.
I have created the "finder" class this way:
/**
* @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;
};
Then I use it the following way:
// 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
}
}
I looped the m_messages vector and there are members that match the id but it2 is always 0x00. Am I doing something particulary wrong?
Thank you very much in advance.
PD: Just in case, other piece of codes useful to understand the problem:
/**
* @struct AppMessage
* @brief Information of a message carrying a result of the App.
*/
struct AppMessage {
int messageId;
float payloadValue;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您必须了解
find_if
内部的作用才能正确使用它。 cplusplus 参考 站点提供了一些基本的代码片段,可能有助于理解算法的实际作用(但请记住,这只是出于教育目的的“伪代码”,而不是实际的实现)。这就是该网站对std::find_if
的描述:您可以看到,为序列中的每个元素调用谓词。在这里,您有一个
std::vector
,因此所提供的谓词应该可以使用AppMessage
进行调用。将谓词更改为此应该可以解决问题:
另请注意,我将
operator()
和m_myMessage
设置为 const(为什么?因为我可以!)。You have to understand what
find_if
does internally in order to use it correctly. The cplusplus reference site offers some basic code snippets which may help understand what an algorithm actually does (but remember it's just 'pseudo-code' for educational purpose, not the actual implementation). This is what this site gives as a description ofstd::find_if
:What you can see is that the predicate is called for each element in the sequence. Here, you have a
std::vector<AppMessage>
so the provided predicate should be callable with anAppMessage
.Changing you predicate to this should do the trick :
Also note that I made
operator()
andm_myMessage
const (why ? because I can !).您的谓词应该采用迭代类型的对象,在您的情况下是 AppMessage。
因此,如果你用这样的东西替换你的operator(),我想你会更接近一些有效的东西:
Your predicate should take an object of the type iterated over, that is an AppMessage in your case.
So if you replace your operator() with something like this, I think you'll get closer to something working:
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) 更有效(典型情况是在具有大量记录的数据库表中搜索一些项目与几次索引查找相比,即使运行一次表也会效率低下)。
Your boolean logic is wrong for find_if which is most likely leading to your error.
As it is, if your vectors are not very short and you are doing this a lot of times, find and find_if are very inefficient as they are linear complexity. Yours uses 2 loops which makes it O(M*N) where M and N are the length of your collections.
Big-O, as it is called, is one of the main keys to efficient programming.
If your collections are both sorted, set_intersect is the way to get all the items that are in both collections which is O(M+N). If they are not, you can sort one of them then subsequently your lookup will be O(M log N) or O(N log M) dependent on which one you sorted. If one is much longer than the other and you sort the longer one, O(M log N) is more efficient than O(M + N) (typical situation is searching for a few items in a database table that has a lot of records. Even running the table once is going to be inefficient compared to a few indexed lookups).