2017-01-12 6 views
0

Возможно ли пройти std::forward_list, увеличивая итератор до тех пор, пока указанный интернатор не станет нулевым? Старомодный способ ...`std :: forward_list` до тех пор, пока итератор не станет нулевым?

В следующем примере я создаю функцию print().

#include <iostream> 
#include <forward_list> 

void print(std::forward_list<int>::iterator fl_it, std::forward_list<int>::iterator e) { 

    while (fl_it != e) { 
     std::cout << *fl_it << ' '; 
     ++fl_it; 
    } 

    std::cout << std::endl; //-> 1 2 3 
} 

int main() { 
    std::forward_list<int> fl = {1, 2, 3}; 
    print(fl.begin(), fl.end()); 
    std::cout << std::endl; 
    return 0; 
} 

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

То, что я хочу сделать, это просто передать итератор к главе списка, и шаг за шагом вперед, пока нет больше элементов, например, так:

void print(std::forward_list<int>::iterator fl_it) { 
    while (fl_it != nullptr) { 
     std::cout << *fl_it << ' '; 
     ++fl_it; 
    } 
    std::cout << std::endl; 
} 

Мой компилятор не нравится это fl_it != nullptr бизнес ,

Моим первым наклонением было найти способ проверить, является ли итератор нулевым, и ссылается на конец списка. К сожалению, такого метода не существует.

Любые идеи?

+2

Думайте об этом так: если бы у вас был первый элемент массива и никакой другой информации, можете ли вы дойти до конца? – AndyG

+2

И вы могли бы * определить * конец, когда вы пришли к нему? – jaggedSpire

+0

Следует отметить, что * есть * некоторые типы итераторов, которые * вид * имеют эту функцию - 'std :: istream_iterator', для одного есть конструктор 'istream &' и конструктор по умолчанию. Построенный по умолчанию итератор действует как конечный итератор для диапазона, а построенный итератором istream будет сравниваться с итератором, построенным по умолчанию, когда он встречает конец обернутого istream. Таким образом, вы можете передать 'istream_iterator' в функцию и просто построить в нем конечный итератор. Но это не относится ко многим типам итераторов. – jaggedSpire

ответ

2

У вас нет.

std::forward_list - это стандартный контейнер для библиотеки. Как и все контейнеры, он идет от begin до end. Нет нулевых итераторов. Поэтому операции выполняются на множестве итераторов.

Обратите внимание, что предложение TS диапазона предназначено, чтобы разрешать типы «дозорного», а не требовать конечных итераторов. Единый дозорный мог сравниваться с конечным итератором любого диапазона. Так что forward_list действительно может быть обновлен, чтобы иметь такое значение.

Но это все равно не будет «нулевым» итератором.

0

Вы должны понимать, что объект итератора не является точно указателем. Это объект и представляет собой позицию элемента в структуре данных. Также приращение итератора конца не приводит к нулевому итератору. Это неопределенное поведение. Посмотрите на Can an STL map iterator go out of bounds through incrementing?

0

Итератора не является нулевым, когда в конце списка, а оно равно к списку в конце итератораfl.end(). Поэтому итераторы должны быть переданы функции.

Внутренняя реализация итератора зависит от используемой библиотеки STL, для std::forward_list ее интерфейс таков, что он выполняет концепцию ForwardIterator: http://en.cppreference.com/w/cpp/concept/ForwardIterator.

+0

«оба итератора должны быть переданы функции« <- кажется сота анти-тематической, в которой связаны связанные списки, нет? Не имеют ли привязанные однонаправленные списки конечный маркер? Мы должны быть в состоянии идти вместе, пока мы не достигнем конца линии. – kmiklas

+0

Внутренне 'fl.end()', вероятно, представляет значение дозорного, и сравнение его с конечным итератором фактически проверяет, является ли указатель нулевым (в зависимости от того, как реализуется 'std :: forward_list'). Но в STL для всех типов контейнеров два итератора всегда используются для итерации по списку. – tmlen

Смежные вопросы