简体   繁体   English

std :: list :: erase(iter)异常处理C ++

[英]std::list::erase(iter) exception handling c++

I try to get an iterator from a function and then erase an element from a list. 我尝试从函数中获取一个迭代器,然后从列表中删除一个元素。

  1. Is there any way to catch that exception? 有什么办法可以捕获该异常?
  2. Is there any way to know if the iterator is valid? 有没有办法知道迭代器是否有效?

When I run the program with invalid iterator it throws the following exception: 当我使用无效的迭代器运行程序时,它将引发以下异常:

 Exception thrown: read access violation.
 _Right.**_Myproxy** was 0xCCCCCCCC. occurred

My func is: 我的功能是:

list<AccountStruct>::const_iterator SearchAccount(list<AccountStruct>& Acc,string p)
{

    for (list<AccountStruct>::const_iterator j = Acc.begin(); j !=Acc.end(); ++j)
    {
        if ((*j).phone == p) return j;
    }

}

void RemoveAccount(list<AccountStruct>& Acc)
{
    string Phone;
    cout << "Enter Phone Number ->" << endl;
    cin >> Phone;
    //cout << "Searching..." << endl;
    list<AccountStruct>::const_iterator iter = SearchAccount(Acc,Phone);
    try
    {
        Acc.erase(iter);
    }
    catch()// <- What to put inside??
    {
        cout << "No Phone Number;" << endl;
    }

}

We can fix this with a couple changes. 我们可以通过一些更改来解决此问题。 First, SearchAccount doesn't return anything if the function does not find an object. 首先,如果函数找不到对象,则SearchAccount不会返回任何内容。 This is undefined behavior, as you must return something when you say you will. 这是未定义的行为,因为您必须在声明时返回某些内容。 We can fix this by returning end() if the item is not found like find does. 如果find该项目,我们可以通过返回end()来解决此问题,就像find一样。 That gives you 那给你

list<AccountStruct>::const_iterator SearchAccount(list<AccountStruct>& Acc,string p)
{
    for (list<AccountStruct>::const_iterator j = Acc.begin(); j !=Acc.end(); ++j)
    {
        if ((*j).phone == p) return j;
    }
    return Acc.end(); // item not found
}

Now that SearchAccount functions properly we can then check to see if end() is returned instead of using the exception mechanism. 现在SearchAccount可以正常运行了,我们可以检查是否返回了end()而不是使用异常机制。 That look like 看起来像

void RemoveAccount(list<AccountStruct>& Acc)
{
    string Phone;
    cout << "Enter Phone Number ->" << endl;
    cin >> Phone;
    //cout << "Searching..." << endl;
    list<AccountStruct>::const_iterator iter = SearchAccount(Acc,Phone);
    if (iter != Acc.end())
    {
        Acc.erase(iter);
    }
    else
    {
        cout << "No Phone Number;" << endl;
    }
}

And now you don't have the overhead of the exception mechanism and the "right thing" happens. 现在,您不再需要异常机制的开销,并且发生了“正确的事情”。

You should use ::std::remove_if algorithm 您应该使用::std::remove_if算法

Acc.erase
(
    ::std::remove_if
    (
        Acc.begin()
    ,   Acc.end()
    ,   [&Phone](AccountStruct const & acc)
        {
            return(acc.phone == Phone);
        }
    )
,   Acc.end()
);

std::list::erase does not throw any exception. std::list::erase不会引发任何异常。

The try block is not necessary. 不需要try块。 However an invalid iterator will cause undefined behavior. 但是,无效的迭代器将导致未定义的行为。

You could return Acc.end() at after the for loop in SearchAccount and check the returned value against Acc.end instead of using try . 你可以返回Acc.end()在后的for中环SearchAccount和核对返回的值Acc.end而不是使用try

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM