В Пример 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)
). (Здесь происходит вывод аргумента шаблона?)
Да, это действительно.
Там нет вывода аргумента шаблона, кроме того, что вы уже обычно вызываете: ваш первый аргумент имеет тип directory_iterator
Таким образом, функция создается как таковая.
Исходя из этого, шаблоны в стороне, теперь вы вызываете функцию, которая занимает два directory_iterators
: {}
Можно только инициализировать directory_iterator
в этот момент, поскольку это то, что принимает ваша функция [экземпляр шаблона]. Следовательно, в этом случае, написание {}
функционально эквивалентно письму directory_iterator{}
,
Если directory_iterator
не может быть построен из {}
, ваша программа не будет компилироваться.
Вот различные перегрузки для 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()
,