Является ли {} допустимым аргументом для передачи функции, ожидающей итератор (представляющей std :: end () некоторого контейнера)?

В Пример boost directory_iterator — как вывести список файлов каталогов не рекурсивно (увидеть этот ответ) это пример кода

#include <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>

...
using namespace boost::filesystem;

for(auto& entry : boost::make_iterator_range(directory_iterator(p), {}))
{
std::cout << entry << "\n";
}

(p имеет тип boost::filesystem::path.)

Посмотрев на документация для make_iterator_range, я считать вызываемый конструктор это:

template< class ForwardTraversalIterator >
iterator_range< ForwardTraversalIterator >
make_iterator_range( ForwardTraversalIterator Begin,
ForwardTraversalIterator End );

Если я прав, то второй аргумент передается в приведенном выше примере кода, {}, кажется, соответствует концу любого контейнера, который невидимо повторяется directory_iterator,

Я никогда не видел этого раньше.

Можно ли построить end итератор просто путем создания значения такого итератора из пустого списка инициализатора {}? (Я даже правильно формулирую это?)

Я не против того, чтобы кто-то объяснил, что происходит под капотом, учитывая, что тип построенного итератора должен соответствовать типу первого итератора (directory_iterator(p)). (Здесь происходит вывод аргумента шаблона?)

4

Решение

Да, это действительно.

Там нет вывода аргумента шаблона, кроме того, что вы уже обычно вызываете: ваш первый аргумент имеет тип directory_iteratorТаким образом, функция создается как таковая.

Исходя из этого, шаблоны в стороне, теперь вы вызываете функцию, которая занимает два directory_iterators: {} Можно только инициализировать directory_iterator в этот момент, поскольку это то, что принимает ваша функция [экземпляр шаблона]. Следовательно, в этом случае, написание {} функционально эквивалентно письму directory_iterator{},

Если directory_iterator не может быть построен из {}, ваша программа не будет компилироваться.

3

Другие решения

Вот различные перегрузки для boost::make_iterator_range:

template< class ForwardTraversalIterator >
iterator_range< ForwardTraversalIterator >
make_iterator_range( ForwardTraversalIterator Begin,
ForwardTraversalIterator End );

template< class ForwardRange >
iterator_range< typename range_iterator<ForwardRange>::type >
make_iterator_range( ForwardRange& r );

template< class ForwardRange >
iterator_range< typename range_iterator<const ForwardRange>::type >
make_iterator_range( const ForwardRange& r );

template< class Range >
iterator_range< typename range_iterator<Range>::type >
make_iterator_range( Range& r,
typename range_difference<Range>::type advance_begin,
typename range_difference<Range>::type advance_end );

template< class Range >
iterator_range< typename range_iterator<const Range>::type >
make_iterator_range( const Range& r,
typename range_difference<const Range>::type advance_begin,
typename range_difference<const Range>::type advance_end );

Поскольку в вашем коде уже указано, что первый параметр имеет тип
directory_iteratorединственный допустимый тип для второго параметра directory_iterator, Это недвусмысленный.

Следовательно, тип указывать не нужно. {} является синонимом directory_iterator{}, что также является синонимом directory_iterator(),

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector