如何将find_if与链表等非容器一起使用?

howto use find_if with non-container such as linked list?

本文关键字:一起 链表 find if      更新时间:2023-10-16

我正在尝试对静态对象列表进行算法支持。我尝试过各种方式,但我能让它工作的唯一方法是编写一个传统的 C for 循环。

例:

class ListNode
{
public:
ListNode(int id);
virtual ~ListNode() {}
// Container support functions
ListNode* operator++() {return m_nextNode;}
static ListNode* findNode(int p_id);
static ListNode* m_nodeList{nullptr};
private:
int m_id;
ListNode *m_nextNode;
protected:
static void addNewNode(ListNode* p_node);
friend ListNode* begin(void);
};
inline ListNode* begin(void) {return ListNode::m_nodeList;}
inline ListNode* end(void) {return nullptr;}
// Declare the list head
ListNode* ListNode::m_nodeList = nullptr;
// Constructor
ListNode::ListNode (int id): m_id{id}
{
ListNode::addNewNode(this);
}
// Add node to front of list
void ListNode::addNewNode(ListNode* p_node)
{
p_node->m_nextService = m_nodeList;
m_nodeList = p_node;
}
//
// The following are all the find implementation attempts
//
ListNode* ListNode::failedFind1(int id) {
return std::find_if(ListNode::m_nodeList,
static_cast<ListNode*>(nullptr),
[p_serviceNumber](const ListNode& s) {
return id==s.m_id;
}
);

我还使用定义的begin()end()函数尝试了此操作。唯一有效的方法是:

for (auto *s = m_nodeList; s != nullptr; s = s->m_nextNode)
{
if (s->m_id == id)
return s;
}
return nullptr;

我错过了什么?

感谢您的反馈。

我为安全关键应用开发软件。通常不允许使用动态内存。STL 链表类是用于维护对象列表的独立数据结构。我们有对象,只需要它们作为 STL 兼容的容器对象。(这就是原因(

这个链接非常有用。问题是增量运算符的定义错误。

问题是你的begin/end函数返回一个指针,所以当find_if++递增指针时,它只是递增指针指向第一个节点之后的垃圾,并且不使用你的operator++

你需要定义一个迭代器类对象,它定义了(一元(operator*operator++,并让开始/结束返回它。 此迭代器类可能只包含一个指针字段。

研究调试器的问题,这就是我发现的。将ListNode*定义为迭代器,STL将其解释为随机访问迭代器,而不是前向交互器。在这种情况下,它期望 begin(( 和 end(( 是指向数组的指针,在那里可以减去它们以确定关系。由于 end(( 被定义为 nullptr,find_if(( 算法不会执行增量运算符并立即中止,返回 end((。

所以我需要弄清楚如何定义一个forward_iterator以便列表遍历正常工作。