通过引用从 std::vector 中删除节点
Removing a Node by reference from std::vector
我对C++相对较新,所以请原谅任何疏忽。
我有一个包含 id 和位置的自定义 Node 类。在代码的主要部分,我创建了一个向量,std::vector<Node>candidateNodes
,并将一堆新创建的节点推入其中。
我有一个函数,expandCandidate Node,它从候选节点的向量以及向量本身中获取其中一个节点,并用它做一些事情:
expandCandidateNode(Node &candidateNode, std::vector<Node> &candidateNodes)
在函数结束时,我想从候选节点向量中删除候选节点。我尝试使用这个堆栈溢出问题的解决方案,它看起来像这样:
candidateNodes.erase(std::remove(candidateNodes.begin(), candidateNodes.end(), candidateNode), candidateNodes.end());
但是,当我尝试构建项目时,出现以下错误:
1>c:Program Files (x86)Microsoft Visual Studio 10.0VCincludealgorithm(1815): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Node' (or there is no acceptable conversion)
我仔细观察了一下,发现错误源于算法类中的模板函数 delete。我真的不确定从这里开始做什么。我的目的是让 candidateNodes 向量搜索与 candidate Node 具有相同引用的节点(基本上确保它们是内存中的相同对象),并将其删除,但似乎 == 运算符无法比较它们的引用?我可能误解了什么。如果有人能澄清我如何正确从向量中删除节点,鉴于它的参考,将不胜感激。谢谢。
>std::remove
有两种风格:
您使用的std::remove
将值作为第三个参数,并使用相等运算符 ==
将其与元素进行比较。您的Node
类似乎不支持这些比较,因此您会在进行比较的标准库深处的某个地方遇到错误。
另一种选择是 std::remove_if
.它不是要比较的值,而是将可调用对象作为第三个参数。它将范围内的对象传递给该可调用对象,并期望一个可转换为布尔值的结果,以告知是否应删除该元素。
因此,如果您希望您的Node
与一般的==
相当,则必须定义该运算符,然后可以使用std::remove
:
bool operator== (Node const& lhs, Node const& rhs) {
return lhs.id == rhs.id && lhs.position == rhs.position;
}
而刚刚的电话remove
就像你一样。
另一种选择是向std::remove_if
提供函数对象。这可以通过 C++11 lambda 表达式来完成,也可以通过在 C++03 中提供手写函子来完成:
C++11:
candidateNodes.erase (
std::remove_if (
candidateNodes.begin(),
candidateNodes.end(),
//here comes the C++11 lambda:
[&](Node const& node) {
return node.id == candidateNode.id && node.position == candidateNode.position;
}
),
candidateNodes.end()
);
或C++03:
struct cmpNode {
Node const& candidateNode;
cmpNode(Node const& cn) : candidateNode(cn) {}
bool operator()(Node const& node) {
return node.id == candidateNode.id && node.position == candidateNode.position;
}
};
candidateNodes.erase(
std::remove_if(
candidateNodes.begin(),
candidateNodes.end(),
//here comes the C++03 functor:
cmpNode(candidateNode);
),
candidateNodes.end()
);
这样做,
struct Node
{
int id;
int position;
};
struct Node targetNode; //the node you want to move
bool comp(const Node& element)
{
return ((element.id == targetNode.id) && (element.position == targetNode.position));
}
candidateNodes.erase(std::remove_if(candidateNodes.begin(), candidateNodes.end(), comp), candidateNodes.end());
>std::remove
使用operator==
来执行检查。您仍然需要将此运算符添加到Node
类中。
我建议您创建一个良好的运算符实现,依赖于Node
、id
和/或position
的唯一数据。
- 删除C++中带有 vector<const char *> 的类
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 为什么通过 vector<reference_wrapper> 的元素删除引用的值<T>不会使向量无效?
- C++从 std::vector<std::function<中删除 std::function>>
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- 从 std::vector 中删除项目时"Iterator not incrementable"
- 如何在不使用 vector::erase() 的情况下编写自定义 Vector 方法来删除元素?
- 在Visual Studio中删除成员std::vector::d ata()
- 在迭代 std::vector 时删除(间接)
- 删除[]是否可以与通用数组正常使用?如果是这样,为什么使用std :: vector ::擦除它会导致释放内存的错误
- 如何通过长度从 std::vector 中删除元素<string>(擦除不起作用)
- 从多个 std::vector 中删除项目的最快方法
- 从 std::vector 中删除原始指针
- C++ vector::erase 抱怨过载解析和删除运算符'=='
- 擦除范围从std :: vector删除向量的最佳方法
- STD :: vector在清除或删除POD方面的行为会有所不同
- std::vector 删除重复项,然后删除另一个向量中的相同索引
- 拒绝std::vector删除其数据
- C++ std::vector 删除 MyClass 对象
- 通过 <vector> 删除复制构造函数等,按值(无指针)将具有相同基类的对象存储在C++中