在过去的6年里,我几乎都是C#程序员。我现在正在开发一个项目,其中C ++是首选语言,STL是我们的集合库。
在使用C#的LINQ之后,我很难进入STL框架。
作为一个例子:写一个等效的IEnumerator.Select。
C#
public static IEnumerator<Output> Select(this IEnumerator<Input> input, Func<Input, Output> func) {
while (input.MoveNext) {
yield return func(input.Current);
}
}
非常容易。
现在尝试用C ++和STL编写类似的东西。 (抛开yield关键字和匿名函数的方便语法问题)。
如果没有先回答一些棘手的问题,甚至无法做到。由于STL枚举器使用的是枚举器间比较而不是MoveNext,因此您必须确定枚举器的终端值。然后你必须弄乱所有的iterator_traits废话。 STL使用编译时模板调度而不是运行时动态调度,因此您的迭代器不仅要模板化输入枚举器的value_type,还要模板化特定类型的输入枚举器。
当我尝试在STL中编写map-join迭代器时,甚至不让我开始。
通过查看其他人编写的代码,我得出的结论是,未使用Boost的STL很少用于集合和排序以外的任何其他内容。
我的近端观察是:
更一般地说,我注意到一些与我习惯的思维方式相冲突的事情:
答案 0 :(得分:2)
你的一些问题对我来说并没有多大意义。例如,您谈到必须处理“enumerator_traits”。我不太确定你在谈论什么。也许你的意思是iterator_traits
?我不记得曾经使用过任何名为“enumerator_trait”的东西,在C ++标准中也找不到这样的东西。
iterator_traits
至少存在,但它们是我很少“混乱”的东西。我周围都知道他们的存在,但仅仅是那个。我编写了大量的迭代器和算法,而没有对任何特定的iterator_traits
做任何特定的事情。
让我们来看看创建一个新集合的具体问题,该集合是另一个集合的排序版本。这在很多方面都相当容易。 std::partial_sort_copy
当然可以做到:
#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>
int main() {
std::vector<int> input;
// generate some data to sort
std::generate_n(std::back_inserter(input), 20, rand);
// a destination for the sorted data:
std::vector<int> result(input.size());
// do the sort/copy:
std::partial_sort_copy(input.begin(), input.end(),
result.begin(), result.end());
// show the sorted data:
std::copy(result.begin(), result.end(),
std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
然而,出于许多目的,制作副本更容易,然后排序:
std::vector<int> result(input.begin(), input.end());
std::sort(result.begin(), result.end());
如果你真的想要它简洁,你可以复制到一个天生排序的数据结构:
std::multiset<int> result(input.begin(), input.end());
然而,最后这种情况通常会使代码缩短效率。在许多(大多数?)情况下,这不是一个问题,但如果你发现它太慢,可以很容易地获得更快的替代品。