Как вернуть итератор из функции, включая конечный случай - PullRequest
1 голос
/ 05 мая 2019

В c ++ мне нужно искать вектор, содержащий пару, в обратном порядке, по строке.Я не могу использовать карту, потому что строки не уникальны и порядок важен.Затем я хочу вернуть прямой итератор, если строка найдена, или конечный итератор, если строка не найдена.

Пожалуйста, см. Ниже мой текущий код.У меня нет проблем, когда строка найдена, но, если строка не найдена, я получаю segfault в условном выражении в main.

vector<pair<string, int>>::iterator prev_it(const string& pred, 
        vector<pair<string, int>> prevpreds) {
    vector<pair<string, int>>::reverse_iterator rit;
    for(rit = prevpreds.rbegin(); 
            rit != prevpreds.rend(); ++rit) {
        if (rit->first == pred) {
            return (rit+1).base();}
    }
    if(rit == prevpreds.rend()) {
        return prevpreds.end();
    }
}

и в main:

int main() {
    vector<pair<string, int>> test;
    for(int i = 0; i <= 5; ++i) {
        pair<string, int> mypair;
        mypair = make_pair("X"+to_string(i%4+1), i+1);
        test.emplace_back(mypair);
    }
    string tpred = "X"+to_string(6);

    vector<pair<string, int>>::iterator tit;
    tit = prev_it(tpred, test);

    if (tit != test.end()) {
        cout << tit->first << " " << tit->second << endl;
    }
    else {cout << "This is the end." << endl;}
}

Код работает, если tpred является одним из X1-X4.Если tpred X6 (т.е. не элемент теста), то я получаю segfault.То, что я хотел бы сделать, это вернуть итератор конца вперед и затем, как и в main (), получить условное основание на этом.

Редактировать: Я новичок в c ++ (около года).Я возвращаю прямой итератор, потому что мне нужно использовать итератор позже, и это кажется более ясным (но я могу ошибаться).Насколько я понимаю, мультикарта допускает неуникальные ключи, но заказывает уникальные ключи.Я должен был быть более ясным и сказал, что порядок времени важен, а не ключевой порядок.Я предпочитаю не использовать auto при разработке, потому что мне нравится видеть, какой контейнерный элемент / итератор я использую, но при этом учтено.

1 Ответ

1 голос
/ 05 мая 2019

Вы используете итератор разрушенного объекта. Передайте prevpreds по ссылке, чтобы итератор поддерживал действительность.

vector<pair<string, int>>::const_iterator prev_it(const string& pred,
                                        const vector<pair<string, int>> &prevpreds)
{
    vector<pair<string, int>>::const_reverse_iterator rit;
    for (rit = prevpreds.rbegin();
            rit != prevpreds.rend(); ++rit)
    {
        if (rit->first == pred)
        {
            return (rit + 1).base();
        }
    }

    return prevpreds.end();
}

int main()
{
    // ...

    vector<pair<string, int>>::const_iterator tit; // <-- uses const iterator
    tit = prev_it(tpred, test);

    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...