C++ std::end如何知道数组的结尾?

C++ std::end如何知道数组的结尾?,c++,arrays,c++11,C++,Arrays,C++11,std::begin和std::end知道容器或数组的开头和结尾 例如,很容易知道向量的结束和开始,因为它是提供此信息的类。但是,它如何知道像下面这样的数组的结尾 int simple_array[5]{1, 2, 3, 4, 5}; auto beg=std::begin(simple_array); auto en=std::end(simple_array); std::begin不难知道数组从哪里开始。但它怎么知道它的结局呢?常量整数5是否会存储在某个地方 如果我能得到一些低级信息的答

std::begin
std::end
知道
容器或
数组的开头和结尾

例如,很容易知道
向量的
结束
开始
,因为它是提供此信息的类。但是,它如何知道像下面这样的
数组的结尾

int simple_array[5]{1, 2, 3, 4, 5};
auto beg=std::begin(simple_array);
auto en=std::end(simple_array);
std::begin
不难知道数组从哪里开始。但它怎么知道它的结局呢?常量整数
5
是否会存储在某个地方

如果我能得到一些低级信息的答复,我将不胜感激

但是,它如何知道数组的结尾呢

它使用一个模板非类型参数来推断数组的大小,然后可以使用该数组生成结束指针。CPP参考部分的C++11签名如下:

template< class T, std::size_t N >
T* end( T (&array)[N] );
模板
T*end(T&数组)[N]);
正如hvd所指出的,由于它是通过引用传递的,因此可以防止指针衰减

实施类似于:

template< class T, std::size_t N >
T* end( T (&array)[N] )
{
    return array + N ;
}
模板
T*结束(T(&数组)[N])
{
返回数组+N;
}
是常量整数5将存储在什么地方

5
N
是数组类型的一部分,因此
N
在编译时可用。例如,应用于数组将得到数组中的总字节数


很多时候,我们看到数组按值传递给函数。在这种情况下,要键入的数组存储在数组中。所以现在大小信息丢失了。通过引用传递允许我们避免信息丢失,并从类型中提取大小
N

因为您要将数组传递给
std::end
,并且数组的类型为
T[N]
std::end
可以通过查看类型中的
N
来判断数组何时结束

是常量整数5将存储在什么地方

是的,它是数组类型的一部分。但是不,它没有明确地存储在任何地方。当你有

int i[5] = { };
i
的类型是
int[5]
。Shafik的回答谈到如何使用此长度来实现
end

如果您使用的是C++11,那么使用
constexpr
将是一种简单的方法

template <typename T, size_t N>
inline constexpr size_t
arrLen(const T (&arr) [N]) {
    return N;
}
首先,我们声明一个函数,返回对N
char
s数组的引用,即
sizeof
此函数现在将是数组的长度。然后我们有一个宏来包装它,这样它在调用者端是可读的


注意:相同基本类型但长度不同的两个数组仍然是两种完全不同的类型
int[3]
int[2]
不同,但是,在这两种情况下都会得到一个
int*
。如果您想了解更多信息,请阅读。

谢谢,这是否意味着N存储在某个地方?如果是,函数将?N存储在何处。一旦函数完成执行,它就会丢失。如果你想达到同样的效果并返回数组的大小,你可以使用这个答案中提供的代码,只返回N.@HumamHelfawi你知道我之前没有注意到你的评论,在我与你交流时意识到了你的意思。我更新了我的答案,以适当地涵盖你的评论。是的,现在我更清楚了。。非常感谢@ShafikYaghmour@HumamHelfawi:实际上,数组大小确实存储在代码中=>的某个位置。对于每个不同的元组
(T,N)
,将生成
std::end
的不同实例,并将其作为代码存储在发出的库/二进制文件中。优化编译器可能会意识到它是无用的,并对它进行优化(只留下结果
array+N
),但即使如此,这个N也会因此出现在生成的代码中(作为常量)。谢谢,我似乎错过了很多东西。。我真的应该问“什么是数组”。。你的意思是数组是一个很小的类,有一个指向开始的指针和一些元素?你能给我指一些我能详细阅读的东西吗?两个相同基类型但长度不同的数组仍然是两种完全不同的类型
int[3]
int[2]
不同。然而,在这两种情况下,数组衰减都会得到
int*
。如果你想了解更多关于数组的信息,请阅读。是的,这正是我从你的回答中得出的结论。谢谢again@HumamHelfawi一个
int[5]
数组在内存中只有5个
int
s相邻。运行时,该大小不会存储在任何位置。该大小在编译时可用,因为它是数组类型的一部分。
template <typename T, size_t N>
char (&arrLenFn(const T (&arr) [N]))[N];

#define arrLen(arr) sizeof(arrLenFn(arr))