我假设STL函数只能用于STL数据容器(比如vector
),直到我看到这段代码:
#include#include #include using namespace std; int main() { int a[] = {9, 8, 7}; cerr << "Sum: " << accumulate(&a[0], &a[3], 0, plus ()) << endl; return 0; }
它编译并运行时没有任何警告或g ++错误,给出正确的输出和24.
是否允许 C++/STL 标准允许使用具有STL功能的数组?如果是,那么像数组这样的古老结构如何适应模板化迭代器,容器和函数的宏STL计划?此外,程序员应该注意这些用法中是否有任何警告或细节?
好吧,你问一个阵列.你可以很容易地得到一个指向它的元素的指针,所以它基本上归结为指针是否可以透明地与STL函数一起使用的问题.指针实际上是迭代器中最强大的一种.有不同的种类
输入迭代器:只有正向和一次通过,只能读取
输出迭代器:只有正向和一次通过,只能写入
转发迭代器:仅转发和读/写
双向迭代器:前向和后向,以及读/写
随机访问迭代器:一次向前和向后任意步进,读/写
现在,第二组中的每个迭代器都支持前面提到的所有迭代器的所有内容.指针模拟最后一种迭代器 - 随机访问迭代器.您可以添加/减去任意整数,您可以读写.除输出迭代器之外的所有迭代器operator->
都可以用来访问我们迭代的元素类型的成员.
通常,迭代器有几个typedef作为成员
value_type - 迭代器迭代的内容(int,bool,string,...)
reference - 对value_type的引用
指针 - 指向value_type的指针
difference_type - 两个迭代器之间的距离是什么类型(返回std::distance
).
iterator_category - 这是一个标记类型:它被typedefed为一个表示迭代器类型的类型.要么std::input_iterator_tag
,... std::random_access_iterator_tag
.算法可以使用它来重载不同类型的迭代器(就像std::distance
随机访问迭代器更快,因为它只能返回a - b
)
现在,指针当然没有那些成员.C++有一个iterator_traits
模板,专门用于指针.所以,如果你想获得任何迭代器的值类型,你就可以了
iterator_traits::value_type
无论是指针还是其他迭代器,它都会为您提供该迭代器的value_type.
所以 - 是的,指针可以很好地与STL算法一起使用.正如别人提到的,甚至std::vector
可以是一个T*
.指针甚至是迭代器的一个很好的例子.因为它非常简单但同时又如此强大以至于它可以在一个范围内迭代.
该标准设计了迭代器,使其感觉和行为尽可能像指针一样.此外,由于迭代器基于模板,唯一相关的是迭代器类型具有定义的适当运算符.结果是指针开箱即用的行为就像随机访问迭代器一样.
事实上,一个可能的实现std::vector
就是让它成为一个T*
.
当然,对于一个数组,你将没有找到有效迭代器范围的有用begin()
和end()
方法,但这是C风格数组总是存在的问题.
编辑:实际上,正如评论和其他答案中所提到的,如果数组不是动态的并且没有衰减成指针,则可以为数组实现这些函数.但我的基本观点是,你必须比使用标准容器时更加小心.
简短回答:STL算法通常被定义为与各种迭代器一起使用.迭代器由它的行为定义:它必须可以用*解除引用,它必须可以用++递增,以及各种其他的东西也定义它是什么类型的迭代器(最常见的是随机访问).请记住,STL算法是模板,因此问题是语法之一.类似地,使用operator()定义的类实例在语法上与函数一样,因此它们可以互换使用.
指针执行随机访问迭代器所需的一切.因此,它是一个随机访问迭代器,可以在STL算法中使用.你可以看看矢量实现; 你很可能会发现那vector
是一个whatever *
.
这不会使数组成为有效的STL容器,但它确实使指针成为有效的STL迭代器.