例如:
v.for_each([](int i) { printf("%d\n", i); });
如果比常用的更优雅和可读:
std::for_each(v.begin(), v.end(), [](int i) { printf("%d\n", i); });
标准中缺少这样的成员函数是否有正当理由?
答案 0 :(得分:8)
这是整个库的标准设计原理:将容器与算法分开。
如果您按照自己的方式进行操作,则必须为每个容器Y实现每个功能X,如果您有M个功能和N个容器,则可以使用M * N实现。
通过使用迭代器和make算法处理迭代器而不是容器,你只需要实现M算法和N迭代器接口。
这种分离也意味着你有更广泛的应用范围:算法不仅可以用于每个库容器,而且可以用于任何容器,现在或将来,任何人都决定编写和配备迭代器。有限与无限重用是一个非常有力的论据!通过通用的免费接口调用算法不会增加任何成本。
答案 1 :(得分:2)
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f);
正如您所看到的,for_each将Input Iterator作为参数,因此任何可以提供输入迭代器兼容的stl容器(除了输入迭代器,它也可以是双向,随机访问迭代器等)都将与std兼容: :的for_each。通过这种方式设计,stl通用单独的算法与数据类型(容器)更加优雅和通用的。
答案 2 :(得分:1)
简单的事实是,标准库设计是从语言没有提供许多功能的时候开始的,现在许多常见的设计,例如基于CRTP的mixins,都不存在。这意味着现在显而易见的优秀设计在创建标准库时无法实现或设计。
迭代器是一个很好的通用实现,但它们构成了一个非常通用的通用接口。我觉得很难过,不是用库设计解决问题并对其进行检修,而是为问题的一小部分引入了一种特殊的案例语言功能。
答案 3 :(得分:0)
你为什么需要它?
如果可以提高实现效率,则成员函数仅用于此目的(set :: find比集合上的std :: find()更有效)。
PS 哦,如果您想避免无处不在的.begin()
,请.end()
来电,请使用 Boost Range Algorithms 。甜的语法糖
一个随机的Boost Range启发样本:
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/pending/integer_range.hpp>
using namespace boost::adaptors;
static int mod7(int v)
{ return v % 7; }
int main()
{
std::vector<int> v;
boost::copy(
boost::make_integer_range(1,100) | transformed(mod7),
std::back_inserter(v));
boost::sort(v);
boost::copy(
v | reversed | uniqued,
std::ostream_iterator<int>(std::cout, ", "));
}