C ++为什么没有类似length(array)的东西?

c++ why isn't there something like length(array)?

本文关键字:array length 为什么      更新时间:2023-10-16

好吧,我认为这并不重要,但是由于程序无论如何都必须存储长度[],为什么我们不能获得这些"存储的信息"?

实现只需要存储长度,并且通常只有在类型不是微不足道的可破坏性(即,它需要生成对析构函数的调用)并且数组是使用 new[] 运算符创建的时才这样做。

由于数组类型的该属性与数组的大小无关,因此简单地将长度"cookie"称为私有实现细节会更优雅。

要获取完整数组对象(而不仅仅是指针)的长度,可以使用 std::extent< decltype( arr ) >::valuestd::end( arr ) - std::begin( arr )

new[]与带有析构函数的类一起使用是一种代码异味。改为考虑std::vector。开销与原始new[](考虑需要分配的所有字节,无论它们在哪里)都是一个指针的字节,好处是无数的。

考虑以下情况:

char* a = new char[100];

现在a需要指向至少 100 个字符大的缓冲区,但系统可能已分配更大的缓冲区来实现此目的

考虑到这一点,我们可以看到系统可以自由地立即忘记程序要求的大小,只要它以后仍然可以正确释放缓冲区。(通过记住分配缓冲区的大小或使用一些智能数据结构进行内存分配,其中只需要指向开始的指针)

因此,在一般情况下,您正在寻找的信息实际上并未存储在任何地方。

并非所有数组都由 new 分配。

void f(int* arr, size_t n)
{
  length(arr);  //  ???
}

int main()
{
  int a[5];
  f(a);
}

不过写起来很简单,只需调用(std::end(arr) - std::begin(arr)),尽管它仅适用于数组,而不适用于指向数组开头的指针。

我的理解是,c++的哲学是不要强迫人们使用任何具有潜在成本的功能,除非不可避免。

存储此信息可能会产生额外费用,如果用户不需要这些信息,他们可能不想支付该费用。而且,如果您想要自己存储长度是微不足道的,因此没有理由提供对使用数组的每个人产生成本的语言功能。

对于正确的数组,即 int a[length] ,您已经拥有了该功能:只需

#define length(A) (sizeof(A) / sizeof(*A))

你完成了它。

如果你在谈论用指针来获取数组的长度,那么指针和数组是两个不同的概念,耦合它们是没有意义的,即使适当的数组在需要时"衰减"到指针,并且你通过指针算法访问数组。

但是,即使我们不考虑这一点并讨论技术方面,C++运行时也可能不知道数组的长度是多少,因为new可以依赖 malloc ,它以特定的方式存储数组的长度,只有free才能理解:C++运行时仅在您拥有非空析构函数时才存储额外的信息。一张很乱的图片,是吧?

因为它取决于存储此信息的实现。 所以没有通用的方法可以做一个长度(数组)

长度肯定

不会存储在所有实现中。 例如,C++允许垃圾收集(例如boehmgc),许多收集器不需要知道长度。 在传统的分配器中,存储的长度通常会大于实际长度,即分配的长度,而不是使用的长度。

但是,数组的长度到底是多少?是数组中的字节数还是数组中的元素数?

例如:对于某个 100 字节大小的类 A,

A* 我的数组 = 新的 A[100];

length(myArray) 应该返回 100 还是 100 * 100?有人可能想要100,有人可能想要10000。因此,两者都没有真正的论据。

在支持length(array)的语言中,最像"数组"的c++类型是std::vector<>,它确实std::vector<>::size()

当然,在大小明确的范围内,编译器知道纯[]数组的大小,但也可以将它们传递给编译器不知道大小的作用域。这为 c++ 提供了更多处理类似数组数据的方法而不是必须支持length交互的语言(因为它们必须确保始终传递大小)。