为什么 stl 中没有针对每种集合类型的 for_each 成员函数?
例如:
v.for_each([](int i) { printf("%d\n", i); });
如果比常用的更加优雅和可读:
std::for_each(v.begin(), v.end(), [](int i) { printf("%d\n", i); });
标准中缺少这样的成员函数是否有正当理由?
For example:
v.for_each([](int i) { printf("%d\n", i); });
if far more elegant and readable than the commonly-used:
std::for_each(v.begin(), v.end(), [](int i) { printf("%d\n", i); });
Is there a legitimate reason such a member function is missing from the standard?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是整个库的标准设计原理:将容器与算法分开。
如果您按照自己的方式进行操作,则必须为每个容器 Y 实现每个功能 X,如果您有 M 个功能和 N 个容器,则会导致 M * N 种实现。
通过使用迭代器并使算法在迭代器而不是容器上工作,您只需实现 M 个算法加上 N 个迭代器接口。
这种分离还意味着您拥有无限广泛的应用范围:算法不能仅用于每个库容器,而是可以用于任何人决定的任何容器,无论是现在还是将来编写并配备迭代器。有限重用与无限重用是一个非常有力的论据!通过通用、免费的接口调用算法不会增加任何成本。
This is the standard design rationale for the entire library: Separate containers from algorithms.
If you did it your way, you'd have to implement every feature X for every container Y, leading you to M * N implementations if you have M features and N containers.
By using iterators and make algorithms work on iterators rather than containers, you only have to implement M algorithms plus N iterator interfaces.
This separation also means that you have infinitely wider scope of application: the algorithms cannot just be used for every library container, but for any container, present or future, that anyone decides to write and equip with iterators. Finite vs infinite reuse is quite a strong argument! And calling the algorithms through the generic, free interface doesn't add any cost.
正如您所看到的 for_each 将输入迭代器作为参数,因此任何可以提供兼容输入迭代器的 stl 容器(意味着除了输入迭代器之外,它也可以是双向、随机访问迭代器等)将与 std::for_each 兼容。通过这种方式设计,stl通用的算法与数据类型(容器)分离,更加优雅和方便。通用的。
As you can see for_each takes Input Iterator as in parameter, so any stl container that can provide a input iterator compatible(meaning apart from input iterator, it could also be bidirectional ,random access iterator etc) would be compatible with std::for_each. By designing this way, stl generic separate algorithm from data type(containers) which is more elegant & generic.
一个简单的事实是,标准库的设计源于该语言没有提供很多功能的时代,并且现在常见的许多设计(例如基于 CRTP 的 mixin)都不存在。这意味着现在显而易见的卓越设计在创建标准库时根本无法实现或设计。
迭代器提供了一个很好的通用实现,但它们提供了一个糟糕的通用接口。我感到悲伤的是,他们没有通过库设计来解决问题并对其进行彻底修改,而是针对问题的一小部分引入了一种特殊情况的语言功能。
The simple fact is that the Standard library design is from a time when the language did not offer many features, and many designs common now, such as CRTP-based mixins, weren't around. This means that superior designs that are obvious now simply weren't implementable or designable when the Standard library was created.
Iterators make a great generic implementation, but they make a sucky generic interface. I find it saddening that instead of solving the problem with the library design and overhauling it, instead they introduced one special case language feature for one tiny subset of the problem.
你为什么需要它?
成员函数只有在实现更加高效的情况下才能达到目的(set::find 在集合上比 std::find() 更高效)。
PS 哦,如果您想避免无处不在的
.begin()
、en.end()
调用,请使用 提升范围算法。甜蜜的语法糖随机的 Boost Range 启发样本:
Why would you require it?
Member functions only serve the purpose if the implementation can be made more efficient (set::find is more efficient than std::find() on a set).
PS Oh, and if you want to avoid ubiquitous
.begin()
, en.end()
calls, use Boost Range Algorithms. Sweet syntactic sugarA random Boost Range inspired sample: