ЧАСТЬ 2: Зачем мне нужен прямой итератор для реализации моего настраиваемого std :: search - PullRequest
0 голосов
/ 24 марта 2011

Не думаю, что необходимо читать первую часть, но я включу ссылку только в случае: почему std :: search требует пересылки iters

.....почти там с категориями итераторов (я думаю) .. Я посмотрел вокруг, чтобы найти простую таблицу all-in-1, которая показывает функциональность, доступную от различных типов итераторов .. не смог найти такую, поэтому я попытался расширитьТаблица Страуструпа включает в себя такие вещи, как: способность проходить через диапазон более одного раза и т. д. ... дайте мне знать, если я что-то пропустил или неправильно понял?..или, если есть лучшая таблица, показывающая

* 1 ++ должна быть (де) указана между приращениями

* n ++ может бытьувеличивается более одного раза без ссылки (де) на

* n_save диапазон может быть передан более одного раза и также сохранен / скопирован

------------------------------------------------------------------------------
-  Iterator Operations and Categories                                     
------------------------------------------------------------------------------
Category:        output  input    forward    bidirectional   random-access
Abbreviation:    Out     In       For        Bi              Ran 
------------------------------------------------------------------------------
Read(*1++):              =*p            
Read(*n++):                       =*p        =*p             =*p
Read(*n_save):                    =*p        =*p             =*p

Write(*1++):     *p=             
Write(*n++):                      *p=        *p=             *p=
Write(*n_save):                   *p=        *p=             *p=

Access:                   ->      ->         ->              ->[]

Iteration:        ++      ++      ++         ++--            ++ -- + - += -=
Comparison:               == !=   == !=      == !=           == != < > >= <= 
------------------------------------------------------------------------------

Запись(* n_save) ... не был уверен, что копирование / сохранение файла iter читается или пишется ... поэтому я добавил его в оба?... Я думаю, если вы можете прочитать-передать диапазон более одного раза ... Вы также можете захотеть записать-передать диапазон более одного раза?

Теперь я понимаю, почему std :: search нуждается в прямых итераторах, но не знаю, зачем ему нужно 4 .. будет 2 для & 2 в достаточном количестве?

while (  begin != end  ) {     
if( begin2 == end2 ) {  return found ;  }
}

.. это потому, что end и end2 refd повторяются более одного раза (каждый раз, когда циклы while) ..?

template <class For, class In> 
For search(  For begin, In end, For begin2, In end2 )
{
    For found ;                     
    For pattern_begin = begin2 ;    //refd
    int flag = 0 ;                  

    // search content for pattern 
    while (  begin != end  ) {      //refd

        if ( *begin != *begin2 ) {    //de-refd

            begin2 = pattern_begin ;  //store/copy
            flag = 0 ;
            begin++ ;             //inc


        } else {

            if ( flag == 0 ) { 

                found = begin ;
                flag = 1 ;
            }

            begin++ ;
            begin2++ ;
        }

        if( begin2 == end2 ) {  return found ;  } //refd

    }

    return begin ;
}

1 Ответ

0 голосов
/ 24 марта 2011

Я думаю, что вы извлекли "необходимо увеличить разыменование" из воздуха.

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

Эта функция поиска нуждается в четырех итераторах, поскольку в противном случае просто не было бы способа определить, где заканчивается какой-либо диапазон.Сам по себе итератор не обязательно (обязательно) знает, находится ли он в конце диапазона.

Диапазон в SC ++ L представлен парой итераторов одного и того же типа.Технически алгоритмы могли бы принимать итераторы различного типа для одного диапазона, но это вряд ли имело бы практическое применение и просто делало бы код более подверженным ошибкам.Таким образом, во время компиляции может быть обнаружен по крайней мере один вид ошибок:

void foo(container& a, const container& b, const container& c) {
    std::search(a.begin(), b.end(), c.begin(), c.end());
}

Ошибка здесь заключается в передаче итераторов в разные контейнеры для первых двух аргументов.Но в этом случае это может быть обнаружено во время компиляции, потому что, к счастью, a и b имеют разную константность, поэтому a.begin() возвращает container::iterator, а b.end() возвращает другой тип container::const_iterator.Если всем четырем аргументам разрешено быть разных типов, то эта ошибка приведет к неопределенному поведению во время выполнения.

...