Что такое `std :: set:: iterator`? - PullRequest
       70

Что такое `std :: set:: iterator`?

2 голосов
/ 28 октября 2019

Я наткнулся на следующий странно выглядящий фрагмент кода онлайн (упрощенно).

#include <iostream>
#include <set>

using namespace std;

int main() {
    set<int> myset{1, 2, 3, 4, 5};
    set<int, int>::iterator it = myset.begin();
    cout << *it << endl;
    return 0;
}

Я только что проверил , это компилируется и запускается . (выводится 1 при выполнении)

Я не понимаю определения типа итератора.

Определение myset как set<int, int> myset; недопустимо в качестве второго необязательного параметра шаблона set объявление типа должно быть компаратором, поддерживающим bool operator()(int& const lhs, int& const rhs) const.

Но почему определение итератора не терпит неудачу? Разве его базовый контейнер не должен иметь тот же тип, что и целевой контейнер?

1 Ответ

4 голосов
/ 28 октября 2019

Вы правы, что второй аргумент шаблона недействителен. Это нарушает предварительные условия контейнера, заставляя все это иметь неопределенное поведение. Но есть несколько вещей, которые нужно распаковать здесь в целом, поэтому мы могли бы подумать об этом несколько. Ключевыми моментами являются следующие:

  1. Недопустимый аргумент шаблона должен как-то использоваться экземпляром для запуска сбоя. И это должно использоваться в месте, которое создается вместе с определением класса. Не весь класс всегда создается. Известный пример - функция-член body . Они создаются только по мере необходимости, когда на самом деле вызывается.

  2. Тип iterator может быть псевдонимом. Кроме того, это может быть псевдоним типа, который разделяют несколько разных специализаций набора. В таком случае, немыслимо, что ::iterator зависит только от первого параметра шаблона. Это означает, что созданный вами тип может быть того же типа, который возвращается другим begin.

Но, в конечном счете, это неправильно сформированная программа. Смешивание итераторов из разных контейнеров само по себе не определено, но у вас также есть нарушение предусловия, которое предшествует этому. В общем, это не стоит того, чтобы на нем подчеркивать, так как такой код не должен появляться нигде, кроме как в интеллектуальных упражнениях.

...