为什么没有用于set_union等的便利函数,它们采用容器类型而不是迭代器?
Why aren't there convenience functions for set_union, etc, which take container types instead of iterators?
std::set_union及其同类使用两对迭代器作为要操作的集合。这很好,因为这是最灵活的事情。然而,他们可以很容易地创建一个额外的方便函数,这些函数将更优雅地用于80%的典型用途。
例如:
template<typename ContainerType, typename OutputIterator>
OutputIterator set_union( const ContainerType & container1,
const ContainerType & container2,
OutputIterator & result )
{
return std::set_union( container1.begin(), container1.end(),
container2.begin(), container2.end(),
result );
}
将:
std::set_union( mathStudents.begin(), mathStudents.end(),
physicsStudents.begin(), physicsStudents.end(),
students.begin() );
为:
std::set_union( mathStudents, physicsStudents, students.begin() );
:
是否有这样的便利功能隐藏在某个地方,我只是没有发现?
如果没有,有人能解释为什么它会被遗漏在STL之外吗?
也许有一个更全面的功能集库在boost?(我找不到)
我当然可以把我的实现放在某个实用程序库中,但是很难将这些东西组织起来,以便它们在所有项目中使用,但不会不恰当地聚集在一起。
是否有像这样的便利函数隐藏在我没有找到的地方?
不在标准库中。
如果没有,有谁能解释为什么它会被排除在STL之外吗?
算法的一般思想是它们与迭代器一起工作,而不是容器。容器可以被修改、改变和戳;迭代器不能。因此,您知道,在执行算法之后,它并没有改变容器本身,只是潜在地改变了容器的内容。
也许有一个更完整的功能集库在boost?
提振。Range就是这样做的。当然,提振。Range 比这更多。它的算法不接受"容器";它们接受迭代器范围,而STL容器恰好满足这些条件。它们还具有惰性求值,这对性能很有好处。
使用迭代器的一个原因当然是它更通用,并且适用于非容器的范围,或者只是容器的一部分。
另一个原因是签名会被混淆。许多算法,比如std::sort已经有多个签名了:
sort(Begin, End);
sort(Begin, End, Compare);
其中第二个用于在除标准小于之外的排序时使用自定义比较。
如果我们现在为容器添加一组sort
,我们得到这些新函数
sort(Container);
sort(Container, Compare);
现在我们有两个签名sort(Begin, End)
和sort(Container, Compare)
,它们都接受两个模板参数,编译器在解析调用时会遇到问题。
如果我们改变其中一个函数的名称来解析这个(sort_range, sort_container?),它将不再方便了。
我同意,STL应该采用容器而不是迭代器对,原因如下:
- <
- 简单代码/gh>
- 算法可以为指定的容器重载,即可以使用map::find算法代替std::find ->更通用的代码
- 子范围可以很容易地包装到容器中,就像boost::range 中所做的那样
@Bo Persson指出了一个模棱两可的问题,我认为这是很有道理的。
我认为可能有一个历史原因阻止了这一点,甚至没有真正考虑过。
STL是在标准化过程中相对较晚的时候引入c++的。在它被接受后不久,委员会甚至投票反对考虑在c++ 98中添加更多的新特性(甚至可能在同一次会议上)。当大多数人已经理解了现有的STL,认识到可以从范围之类的东西而不是单个迭代器中获得多少便利时,考虑它已经太晚了。
即使委员会还在考虑新特性,并且有人写了一个允许传递容器而不是离散迭代器的提案,并且可以接受地处理了潜在的歧义,我怀疑这个提案也会被拒绝。许多人(尤其是面向c语言的人)认为STL是对标准库的一个巨大的补充。我相当肯定,相当多的人会认为仅仅为了允许传递一个参数而添加(大量)更多的函数/重载/专门化是完全不可接受的。
使用开始&迭代的End元素允许使用非容器类型作为输入。例如:
ContainerType students[10];
vector<ContainerType> physicsStudents;
std::set_union(physicsStudents.begin(), physicsStudents.end(),
&students[0], &students[10],
physicsStudents.begin());
由于它们是如此简单的实现,我认为不将它们添加到std库中并允许作者自己添加是有意义的。特别是考虑到它们是模板,因此可能增加代码的库大小并跨std添加便利函数将导致代码膨胀。
- 如何在c++迭代器类型中包装std::chrono
- 定义模板参数的迭代器类型
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- 专门C++使用指针值类型的通用迭代器的模板函数?
- C++类字符串类型的迭代器
- 类型不可知的抽象以使用相同的运行时接口处理正向和反向迭代器和范围?
- 如何转换不同类型的迭代器
- 如何从迭代器中找到对的类型
- C++不兼容的迭代器类型
- 如何确定迭代器在 c++ 模板函数中指向的对象的类型?
- 迭代器的模板参数:函数在调用时推断类型?
- 如何推导 std::高级迭代器类型?
- 在 stl 容器包装器中定义迭代器类型
- 从迭代器转换为变量的类型.(C++11 模板)
- 使用迭代器成员函数是否仅适用于某些向量类型"empty()"?
- 如何编写使用迭代器和特定类型的模板化函数
- 从不同类型的容器的迭代器初始化向量
- 对矢量<类型*>迭代器感到困惑
- C++异构类型迭代器的迭代器
- 为什么c++标准需要std::分区来满足不同类型迭代器的不同复杂性