在数组上使用迭代器
Using iterators on arrays
c++ Primer中指出
在c++中,指针和数组是紧密联系在一起的。特别是,我们将看到,当使用数组时,编译器通常会转换.
我想使用迭代器打印数组。下面的程序工作正常,但当我尝试打印arr2
或arr3
时,如果我没有搞错,这是int *
类型,我得到一个错误(判断&操作符的含义如下)。
error: no matching function for call to ‘begin(int*&)’
int main(int argc, char** argv) {
int arr[] = {0,1,2,3,4,5,6,7,8,9};
auto arr2 = arr;
auto arr3(arr); // I think arr2 and arr3 are of same type
for(auto it = std::begin(arr) ; it != std::end(arr) ; ++it)
std::cout << *it << " ";
std::cout << std::endl;
return 0;
}
考虑到语句,如果一个数组被编译器转换成指针,这个程序怎么能用std::begin()
和std::end()
打印arr
的内容,而不能用arr2
或arr3
,如果它们都是指向整数的指针?
编辑
如果我没说清楚,我很抱歉。我希望通过这次编辑能澄清这个问题。现在我知道begin()
和end()
不能使用指针(多亏了答案),我想知道引用的文本是否不正确,因为它指定有一个数组->指针转换。如果文本说的是真的,那么arr
的类型应该是一个指针。在这一点上引用的文本有问题吗?
此外,是否有任何方法,我可以使用begin()
和end()
指针(不是STL容器)指定大小,可能使用以下构造函数?
template< class T, size_t N >
T* begin( T (&array)[N] );
数组很容易转换为指针,但并非总是如此。例如,如果您获取数组的地址或获取引用,则原始数组类型不会丢失:
int a[10];
int (&ar)[10] = a; // fine
int (*ap)[10] = &a; // also fine
然而,当你以一种大多数其他类型都会被复制的方式使用数组时,数组将被转换为指针,而指针将被复制。
在你的例子中,你可以使用arr2,如果你让它是一个引用:
auto &arr2 = arr;
现在arr2
的类型是int (&)[10]
而不是int *
。
因为std::begin
是为数组而不是指针定义的。数组类型与指针类型不同。
这里的问题显然是auto arr2 = arr
将数组类型降级为指针类型。
请注意,问题实际上是在std::end
而不是在std::begin
。毕竟,std::end
如何能够给指针到最后一个+1元素,当它所有的是指向第一个元素的指针?它不能,因此std::end
不能为指针类型定义,因此std::begin
对指针类型没有任何意义。
确切地说,arr
的类型是int[10]
, arr2
和arr3
的类型是int*
。前者可以转化为后者,而后者不能。
这里,auto
将把arr
(数组类型)衰变为一个指针。 std::begin
和 std::end
只能用于容器或数组,而不能用于指针。
源自c++ 11标准
§7.1.6.4汽车说明符 [dcl.spec.auto]
自动类型说明符表示要声明的变量的类型必须从其初始化式推导出来或者函数声明符应该包含尾随返回类型。
你的代码不能在这里工作,因为auto
不能推断数组类型。就像:
char a[5];
auto b[5] = a; // error, a evaluates to a pointer, which does
// not match the array type
要使它工作,只需使用c++容器,如std::vector
:
vector<int> arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::begin
和std::end
使用的参数是C风格的数组。
std::end
的一个可能实现是:
template<class T, std::size_t sizeOfArray>
constexpr T *end(T (&array)[sizeOfArray])
{
return &array[sizeOfArray];
}
这样当你调用std::end(arr)
时,arr
不会在指针中转换(并且关于数组大小的信息不会丢失…该函数只接受包含sizeOfArray
元素作为参数的数组)。
template<class T>
T *end(T array[])
{
// ?
}
将不起作用,因为T array[]
的行为像一个平面指针(T *array
),而不是一个真正的数组,当用作函数参数时。
auto
将数组arr
衰变成一个指针,技巧将不再起作用。
- 迭代器库中的 std::size() 不适用于传递给函数的 C 样式数组
- 自定义 STL 兼容迭代器,用于迭代 2D 数组类的列
- 获取 c++ 中具有恒定长度的数组的迭代器
- 为自定义数组实现迭代器
- 原始数组和 std::array 在 clang++ 和 VC++ 上的不同迭代器行为
- C++程序在迭代到数组的最后一个元素时崩溃
- 有没有办法创建一个花哨的迭代器和相应的新数组,以便检查每个索引的索引值的条件?
- C 迭代器范围使用指针到数组
- 当大小未知时,如何迭代指向数组 (int*) 的指针?
- 是否可以在 C 数组中使用迭代器?
- 迭代器和数组
- STL 迭代器和数组的关系
- 使用迭代器数组读取稀疏信息
- 为什么迭代2D数组的行主要比列主要快
- c++ 11迭代锯齿数组
- 一元函数,接受迭代器元组并产生基本类型
- 迭代c++数组
- 迭代器元组.operator++的实现
- 如何在C和C++中迭代字符串数组
- 用step迭代1D数组和2D数组