我想在运算符重载函数中从向量中删除一个元素

Posted

技术标签:

【中文标题】我想在运算符重载函数中从向量中删除一个元素【英文标题】:i want to remove an element from my vector in an operator opverload function 【发布时间】:2018-07-26 11:42:06 【问题描述】:

,我尝试使用 vector.erease 但出现错误。

这是 Dict 类头:

#include <iostream>
#include <vector>
#include "Node.h"
using namespace std;

template <class K, class V>
class Dict 
protected:
    vector<K> keys;
    vector<Node<V>> values;
public:
    Dict();
    V& operator[](const K &str);
;

这是 dict 类 cpp:

#include "Dict.h"
template <class K, class V>
Dict<K,V>::Dict() ;

template <typename K, typename  V>
V& Dict<K,V>::operator[](const K &str)


    for(int i = 0; i < this->keys.size(); i++)
    
        if(this->keys[i] == str)
        
            return this->values[i].value;
        
    
    this->keys.push_back(str);
    this->values.push_back(Node<V>());

    for(int i = 0; i < this->keys.size(); i++)
        Node<V> n = this->values[i];
        if(n.value == 0)
        
        this->keys.erase(this->keys.begin() + i);
        this->values.erase(this->values.begin() + i);

        

    
    return this->values.back().value;


template class Dict<string, int>;
template class Dict<string, double>;\

这是节点头:

#include <iostream>
#include <vector>
using namespace std;

template <class V>
class Node 
protected:
    Node& operator=(const V& val);
public:
    V value;
;

这是节点 cpp:

#include "Node.h"
template <typename  V>
Node<V>& Node<V>::operator=(const V &dict) 
    this->value = dict;
    return *this;

这是主要的:

int main() 
    Dict<string, int> d1;
    Dict<string,double> d2;
    d1["a"] = 5;
    d1["b"];
    d1.print();
    return 0;

这应该打印 a,5 但它会打印一个很长的红色错误

*** Error in `/home/giftsky/CLionProjects/Dictionary/cmake-build-debug/Dictionary': double free or corruption (out): 

【问题讨论】:

@Qubit 总是有理由使用一切,因此它们为什么存在,但 Yoav Linder 说他们是一个学习者,所以我想在谈话中谨慎行事。这是我刚开始时很感激的事情 如果您的 Node 将值初始化为 0,则对运算符的第一次调用失败。然后它被推入向量并被第二个 for 循环删除。然后你返回 values.back() 这是无效的,因为值是空的 operator[] 中的第二个 for 循环非常非常奇怪。它的目的是什么?如果我不知道它在做什么,我就无法修复它。 要清楚,这里的许多问题之一是您添加了一个默认构造的节点,该节点的值为零,然后您尝试将其删除,然后返回对最后一个的引用空向量的元素。这不是唯一的问题。在调试器中单步执行它,然后会发生什么。 字典或没有字典,你的最后一个for 循环在概念上是不正确的。如果您删除一个项目,i 索引不应增加。您应该完全控制i,方法是让while 循环或类似的循环,而不是使用for 自动增加i 【参考方案1】:

这并不难,这是一个基于迭代器的解决方案。

auto i = keys.begin();
auto j = values.begin();
while (i != keys.end()) 
    if (j->value == 0) 
        i = keys.erase(i);
        j = values.erase(j);
    
    else 
        ++i;
        ++j;
    

但是正如已经指出的那样,如果您添加一个值为 0 的节点,您将删除您刚刚添加的节点,您的程序将失败。我想答案是在after这个循环而不是之前添加新的键和值。

【讨论】:

进程以退出代码 139 结束(被信号 11:SIGSEGV 中断) 在调试器中单步调试。 @YoavLinder 所以你在代码的其他地方有一个错误。从长远来看,最好学会如何自己调试。

以上是关于我想在运算符重载函数中从向量中删除一个元素的主要内容,如果未能解决你的问题,请参考以下文章

小于运算符不能作为成员函数重载

MinGW 中的全局重载运算符 new/delete

std :: sort不会移动向量的元素[关闭]

空身体的重载运算符神奇地工作

运算符重载

为啥我们必须重载“<”运算符才能使用 is_permutation 并包含算法