2011-11-17 52 views
14

独立STL算法(如std::count_if)带有一对迭代器。在我使用这些所有的情况下(在所有的例子,我在网上看到!),我发现自己打字STL算法采用整个容器而不是.begin(),end()作为arg?

std::count_if(myContainer.begin(),myContainer.end(), /* ... */); 

是有一个原因的风格速记模板

std::count_if(myContainer, /* ... */); 

不如果整个集装箱都进行了更多的操作,那么是否提供了这些操作?我是否忽略了它? C++ 11和C++ 03的答案不同吗?

+2

这是一个简单的设计决定。许多人不认为这是一个很好的选择(见http://www.slideshare.net/rawwell/iteratorsmustgo)。 Boost使用他们的Range概念提供这些算法。 – visitor

回答

10

有一个很好的blog-post由香草萨特讨论的问题。要点是,如果为具有相同数量的模板参数的算法过载已经存在,为算法添加基于容器的重载可能会产生歧义。概念旨在解决这个问题。

+0

好吧,那么'std :: count_if_all'或'std :: count_all_if'会做这个工作吗?与std :: sort'('std :: sort_all')和所有其他... –

0

只是因为STL算法连接/使用迭代器与容器交谈。

2

其中一个原因可能是为迭代器范围提供灵活性。您可能不需要通过所有元素的某个迭代:

<iterator> it = myContainer.begin(); 
it++; // do something 
it++; // do something 
... 
std::count_if(it, myContainer.end(), /* ... */); 

而且,你总是可以有一个包装它为您完成此:

template<typename T> 
... count_if (T myContainer, ...) 
{ 
    std::count_if(myContainer.begin(), myContainer.end(), /* ... */); 
} 
+2

在C++ 11中,使用'begin(myContainer)'和'end(myContainer)'以使它也可以用于数组。 – Sjoerd

+1

只需要在容器的一部分上迭代0.1%的情况下,在99.9%的情况下输入“.begin()”和“.end()”(如果可能的话)。 – eudoxos

+1

@Euxodos:是的,这些0.1%的案例可以用count_if(make_range(it,myContainer.end()),/*...*/);''来解决。 - 从历史上看,算法很快就被添加到标准库中,并且迭代器一次是这样一个新颖的想法。如果他们有更多的经验,事情可能会有所不同。但现在看来,他们不能放弃旧事物,也不能添加新事物,除非能够干净地完成。 – UncleBens

2

STL原理和灵活性主要是因为在迭代器而不是容器上操作。这不是一个大问题,你可以重新使用我早年使用的把戏:

#define FULL_RANGE(c) (c).begin(), (c).end() 

std::copy(FULL_RANGE(c), std::ostream_iterator<c::value_type>(cout, "\n")); 
+0

实际上这是一个聪明的技巧,尽管我可能会把它叫做ALL并且现在使用std :: begin和std :: end –

相关问题