Jon*_*ing 2 c++ design-patterns idioms
据我所知,迭代STL集合的习惯看起来像这样:
int a[] = { 1,2,3 };
std::vector<int> v(a, a+3);
std::for_each(a.begin(), a.end(), some_function);
Run Code Online (Sandbox Code Playgroud)
如果我只想处理集合的某个范围,或者做一些更有创意的事情,那么指定第一个和最后一个迭代器是很有用的,但大多数时候,我怀疑我们实际上是想要使用整个集合.所以,我想知道为什么人们在那种情况下烦恼指定迭代器(因为它们总是相同的),并且不只是沿着这些方向使用便利函数:
namespace easy
{
template <class T, class F>
F for_each(T& collection, F function)
{
std::for_each(collection.begin(), collection.end(), function);
return function;
}
}
Run Code Online (Sandbox Code Playgroud)
(当然,这是可能的,这是做事的惯用方式,我从来没有注意到!我是新的C++,虽然).
我绝对是STL的ga-ga.但我记不起实际上曾经使用过for_each.
这个成语是
for ( container::iterator it = coll.begin(); it != coll.end(); ++ it )
Run Code Online (Sandbox Code Playgroud)
C++ 11引入了糖来减少这种情况
for ( auto elem : coll )
Run Code Online (Sandbox Code Playgroud)
这类似于您的便利功能,但使用免费(非成员)std::begin和std::end功能,允许与非标准容器的对象兼容.
另外,查一下(我还没有玩这个,因为它还没有在GCC中),看起来它限制了程序员访问范围的元素,而不是迭代器.
至于使用容器来指代其整个范围,最好保持允许子范围的灵活性.另一种解决方案是为一对迭代器引入一个习惯用法{ begin, end }.有一些争论,我期望C++ 11包含这样的功能
begin( make_pair( begin_, end_ ) ) // == begin_,
end( make_pair( begin_, end_ ) ) // == end_,
for ( auto elem : make_pair( begin_, end_ ) ) // iterates over [ begin_, end )
Run Code Online (Sandbox Code Playgroud)
但在阅读标准后,它似乎pair缺乏此功能.
pair但是,您可以创建自己的类型,以获得灵活的基于范围的for:
template< typename iter >
struct range_type {
iter first, last;
// use friends because Standard specifies these should be found by ADL:
friend iter begin( range_type const &r ) { return r.first; }
friend iter end( range_type const &r ) { return r.last; }
};
template< typename iter >
range_type< iter > range( iter first, iter last )
{ return range_type< iter >{ first, last }; }
// usage:
for ( auto elem : range( begin_, end_ ) ) // iterates over [ begin_, end )
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |