C++ 为什么这样的迭代器是合法的?
这是密码C++ 为什么这样的迭代器是合法的?,c++,arrays,c++11,C++,Arrays,C++11,这是密码 #include <stdio.h> int a[] = {1, 2, 3, 4, 5}; int main() { for (int i : a) printf("%d\n", i); return 0; } #包括 inta[]={1,2,3,4,5}; int main() { 对于(int i:a) printf(“%d\n”,i); 返回0; } 在我看来,for(inti:a)只在a是整数向量时有效。但在上面的代码中,a是
#include <stdio.h>
int a[] = {1, 2, 3, 4, 5};
int main()
{
for (int i : a)
printf("%d\n", i);
return 0;
}
#包括
inta[]={1,2,3,4,5};
int main()
{
对于(int i:a)
printf(“%d\n”,i);
返回0;
}
在我看来,for(inti:a)只在a是整数向量时有效。但在上面的代码中,a是一个整数数组,很像指向整数的指针。为什么这样做?数组不像指针。数组可以衰减为指针,但在非衰减上下文中,它仍然是一个大小已知的数组 在我看来,for(inti:a)只在a是整数向量时有效 你错了 在上面的代码中,a是一个整数数组,非常类似于指向整数的指针 你在这里也错了。数组和指针是两种完全不同的东西 为什么这样做有效
因为这就是Range所做的。它在容器上迭代。数组是一个容器。编译器知道它需要知道的关于该数组的一切
T arr[]
是一个不完整的类型,但它会变得更好,“功能完整”,右边的部分是一个列表,一个定义大小的列表,编译器在编译时知道它,所以它是静态检查的,你知道它的大小,你甚至知道元素;你还需要什么
数组不是指针,为了更好地理解这个问题,你可以从不同的角度来解决这个问题,例如你应该理解,当你把数组传递给一个函数,实际上你在C和C++中解决了一个不能被很好地解决的问题时,没有<代码>无效FO(t ARR[])< />但是您必须使用void foo(T*arr),因为您无法创建一个仅在C/C++中使用数组的真正接口。
如其他答案中所述,数组不是指针。在某些上下文中,它们衰减为指针,这是事实,但仅在某些上下文中int a[] = {1, 2, 3, 4, 5};
a
的类型是int[5]
,一个包含五个int
类型元素的数组。在本例中,一对空方括号告诉编译器推断元素的数量,因此您的定义相当于inta[5]={1,2,3,4,5}代码>
如果您仍然不确信,下面是一段代码,它试图使编译器发出一条错误消息,其中包含a
类型:
template <typename T> struct Type;
int main()
{
int a[] = {1, 2, 3, 4, 5};
Type<decltype(a)> dummy;
}
总而言之:T[N]
是一种类型:具有N
类型T
元素的数组N
是编译时已知的一个整数常量,因此编译器知道数组的最后一个元素在哪里,因此能够生成一个循环,循环遍历所有元素
如果您想了解更多关于数组衰减的信息,我建议您阅读。这是因为它调用了专门用于C数组的std::begin()
和std::end()
。这来自glibc的
:
模板
内联*
开始(_-Tp(&u-arr)[[u-Nm])
{return\uuu arr;}
模板
内联*
结束(_-Tp(&u-arr)[_-Nm])
{返回uu arr+_Nm;}
<代码> > p>因为编译器尊重C++标准。草案n4296明确指出,基于范围的for语句对普通数组有效:
6.5.4基于语句的范围[stmt.ranged]
对于窗体的基于范围的For语句
for ( for-range-declaration : expression ) statement
…
(1.1)-如果_range是数组类型。。。。如果_range是大小未知的数组或
类型不完整,程序格式不正确
和inta[]={1,2,3,4,5}代码>定义了一个由5个整数组成的数组。请检查:这是一个相当奇怪的问题。假设一段代码表现完美,然后假设它不应该因为一个假设而表现完美。“为什么它能工作”的答案显然是“假设是错误的”,因为编译器总是比你更清楚!你为什么不调查这个错误的假设?为什么它不起作用?你为什么不想让它工作?“因为你不能创建一个只有C/C++的数组的真正接口。”——技术上是正确的,因为没有“C/C++”这样的东西。但是你可以在C++中创建这样的接口。但是你可以使用<代码>模板无效的fo(t(& ARR)[n]){} /Calp> @ SergBaleLista是的,它是有效的,而上面的代码就是它的工作原理。
{
auto && __range = a;
for (auto __begin = a, __end = a + 5; __begin != __end; ++__begin)
{
int i = *__begin;
std::printf("%d\n", i);
}
}
template<class _Tp, size_t _Nm>
inline _Tp*
begin(_Tp (&__arr)[_Nm])
{ return __arr; }
template<class _Tp, size_t _Nm>
inline _Tp*
end(_Tp (&__arr)[_Nm])
{ return __arr + _Nm; }
for ( for-range-declaration : expression ) statement