是{}是一个有效的参数传递给期望迭代器的函数(表示某个容器的std :: end())?

时间:2015-07-05 17:52:21

标签: c++ c++11 boost iterator boost-iterators

boost directory_iterator example - how to list directory files not recursive中(请参阅this answer)是示例代码

#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) )。 (这里是模板参数推断吗?)

2 个答案:

答案 0 :(得分:3)

是的,它有效。

除了您通常调用的参数之外,没有模板参数推断:您的第一个参数类型为directory_iterator,因此该函数将被实例化。

接下来,除了模板之外,现在你正在调用一个需要两个directory_iterators的函数:{}只能 初始化一个directory_iterator这就是你的函数[模板实例]所需要的。因此,在这种情况下,写{}在功能上等同于编写directory_iterator{}

如果无法从directory_iterator构建{},则您的程序将无法编译。

答案 1 :(得分: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()的同义词。