如何判断指针是否是指向数组的指针

How to tell if a pointer is the pointer to an array?

本文关键字:指针 是否是 数组 何判断 判断      更新时间:2023-10-16

考虑这个

template <class T>
inline constexpr bool found_to_be_array (T* specimen)
{
if constexpr (std::is_array_v<T>) {
return true;
}
else {
return false;
};
}

问题是,在何种情况下,这将产生可靠的结果?

澄清:我无法更改此功能的占地面积。我没有答案,所以让我在这里发布我的发现。考虑一下:

int ia[]{ 1,2,3,4,5,6,7,8,9,0 };
int iam[3][3][3][3][3]{};
// returns false
auto is_array_1 = found_to_be_array(ia);
// returns true
auto is_array_2 = found_to_be_array(iam);

我仍在研究这个问题,但对于多维数组,found_to_be_array是有效的。

https://godbolt.org/g/ij73Z4

不,这种方法不起作用。参数specimen已经衰减为指针类型(或者它甚至可能一直是指针(;CCD_ 3使用的元编程技术不会以某种方式追溯到调用方。

此外,您正在测试(无意中?(T而不是T*,但更改为后者是行不通的。

如何判断指针是否是指向数组的指针?

指针有类型,这表明它指向什么。当它指向数组时,指针的类型反映了这一点,例如:

int arr[2][2] = {{1,2},{3,4}};
auto x = &arr[0];

在这种情况下,x的类型为int(*)[2]——指向2个int的数组的指针,在这种情况中为{1,2}。如果将该指针增加1,它将指向下一个由2个ints组成的数组,即{3,4}。如果你把这个指针传给你的函数,T将被推导为int[2],结果将是true

在1D阵列的情况下也没什么不同:

int arr[4] = {1,2,3,4};
auto x = &arr;

x类型将为int(*)[4],它也将工作,函数将返回true

但是,如果将数组传递给函数而不是指针,从而迫使它衰减为指向其第一个元素的指针,则数组信息将丢失,因为指针现在的类型为int

auto x = arr;

这里的xint *类型,它不是指向数组,而是指向第一个int,即1。如果您将其增加1,它将指向下一个int,即2,依此类推。如果这是指向数组的指针,则如果您将它增加1,则它将指向数组结束后的下一个字节。将此指针传递给函数将返回false,因为int类型不是数组。

因此,为了回答您的问题,您可以判断指针是指向数组的指针,因为这些信息将在指针类型中提供。

int iam[3][3][3][3][3]{};
// returns true
auto is_array_2 = found_to_be_array(iam);

iam衰减到指向其第一个元素的指针,基本上是在测试iam[0]是否是一个数组,它确实是,因此它可以工作。

一个非null数据指针是否指向数组元素,总是得到答案可能

你问为什么
该语言明确允许您将任何对象视为一个数组的单个元素。当你需要一个序列,想要复制一个琐碎的对象,或者诸如此类的时候,这是非常漂亮的。

因此,每个指针都是以下之一:

  1. 为空指针
  2. 指向数组的元素的指针
  3. 指向数组元素之外的指针,或者
  4. 无效,表示
    1. wild,表示从未初始化,或
    2. 晃来晃去,这意味着指针对象的生命结束了

虽然您可以区分情况1和2或3,但其余情况可能需要分析程序当前运行的完整历史。

您不能更改函数的要求很奇怪/不合理。

如果不能更改函数签名,则无法检测参数是如何生成的(从ptr或数组(,因为该信息已丢失。