2015-07-05 3 views
4

В boost directory_iterator example - how to list directory files not recursive (см this answer) является пример кодаЯвляется {} допустимым аргументом для перехода к функции, ожидающей итератора (представляющей std :: end() какого-либо контейнера)?

#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)

После глядя на documentation for make_iterator_range, я думаю конструктор вызывается это один:

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

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

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

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

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

+5

'{}' будет 'directory_iterator {}'. Некоторые типы итераторов используют дефолтный объект конструкции в 'end'. – Jarod42

+0

@ Jarod42 «boost :: make_iterator_range» знает, что второй аргумент должен быть типа 'directory_iterator' из-за вывода аргумента шаблона?Подумайте об этом, исходя из самого определения 'make_iterator_range', которое я скопировал в этот вопрос, это довольно очевидно, что это так. –

+0

Стоит отметить, что в VS 2013 этот код не будет построен без явного 'directory_iterator {}' в качестве аргумента - простой '{}' не компилируется. Ах, хорошо. Я надеюсь, что это законный C++ 11 с простой '{}'. –

ответ

3

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

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

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

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

1

Вот различные перегрузки для 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

Это, в сочетании с комментарием @ Jarod42, завершит ответ. Благодаря! –