Набор итераторов в C

#c #iterator #set #std

Вопрос:

Можно ли вычесть итератор для набора stl в c ? Как это возможно в векторе…

 int32_t main()
{
    set<int> s = {1, 3, 0, 23};
    vector<int> v = {1, 3, 0, 23};

    int vind = find(v.begin(), v.end(), 1) - v.begin(); //This is ok with no error

    int sind = find(s.begin(), s.end(), 1) - s.begin();  //But this gives error
    cout<<vind <<" " << sind;
    return 0;
}
 

Я не могу понять причину. Почему это невозможно в наборе??

Комментарии:

1. Поскольку, учитывая природу итераторов множества, вычитание не может быть эффективно реализовано. Вы можете использовать функцию std::расстояние. sind = std::distance(find(s.begin(), s.end(), 1), s.begin()); но имейте в виду, что вызов этой функции займет время, пропорциональное возвращаемому индексу. Другими словами, это операция линейного времени, а не операция постоянного времени.

2. @Evg Спасибо, я совершил ту же ошибку в нескольких случаях, когда мне приходилось использовать эту функцию.

Ответ №1:

Итератор std::set is двунаправленный генератор, который не поддерживает operator- взаимодействие между итераторами. (Итератор std::vector is RandomAccessIterator, который поддерживает это.)

Вы можете использовать std::distance вместо этого. (Обратите внимание, что сложность линейна для InputIterator, включая двунаправленный генератор.)

 int sind = std::distance(s.begin(), find(s.begin(), s.end(), 1));