Можем ли мы увеличить итератор на несколько позиций без функции 'advance'? - PullRequest
0 голосов
/ 26 октября 2018

Я знаю, что мы можем использовать функцию advance() для увеличения итератора.Мы также используем iterator++, чтобы увеличить итератор на одну позицию.Почему мы не можем использовать it+=2?

int main()
{
    list<int> l1{1, 2, 3, 5, 6};
    list<int> l2{2, 6, 8};
    auto it = l1.begin();
    advance(it, 2);         //works
    it++;                   //works
    // it+=2;                  //not work
    l2.splice(l2.begin(), l1, it);

    for(int a: l2) cout<<a<<" ";
    cout<<endl;

    return 0;
}

Вы можете запустить приведенный выше код здесь .

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Вы не можете использовать += 2 с этим итератором, потому что в общем случае увеличение итератора std::list<> на произвольное значение является относительно неэффективной операцией.+= не определен для вашего типа итератора специально для того, чтобы помешать вам небрежно / неосознанно использовать эту неэффективную операцию в вашем коде.Вместо этого, если вы действительно хотите это сделать, вы должны использовать std::advance, которая представляет собой функцию «красного флага», предназначенную для того, чтобы подчеркнуть тот факт, что вы, вероятно, делаете что-то неэффективное.std::advance в основном предназначен для создания эскизов кода или для резервного кода, который вряд ли будет выполнен *.Вы не должны безвозмездно использовать std::advance в рабочем коде.Если вы вдруг обнаружите, что полагаетесь на std::advance, это означает, что вам, вероятно, нужно изменить структуру данных.По сути, std::advance похоже на приведение - избегайте его, если только у вас нет очень-очень веской причины его использовать.

В качестве альтернативы вы можете использовать std::next

it = std::next(it, 2);

Эта функциягораздо проще в использовании, чем std::advance.По умолчанию эта функция предназначена для продвижения итератора на 1 шаг вперед, но вы можете указать второй параметр, чтобы переместить его дальше.Опять же, когда значение второго параметра является непостоянным и потенциально большим, его следует рассматривать как функцию «красного флага».Постоянное значение 2 определенно находится в допустимых пределах.

0 голосов
/ 26 октября 2018

operator += поддерживается только RandomAccessIterator ; обратите внимание, что он должен иметь постоянную сложность.

Итератор std::list равен BidirectionalIterator , который не поддерживает operator +=. (Итератор std::vector и std::array является RandomAccessIterator.)

Обратите внимание, что оба они могут использоваться с std :: advance , когда используется для RandomAccessIterator сложность постоянна; при использовании для других InputIterator (включая BidirectionalIterator) сложность является линейной. Это означает, что использование std::advance является хорошей идеей, поскольку оно носит более общий характер и может автоматически использовать преимущества RandomAccessIterator.

...