考虑这个
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
有用。
答案 0 :(得分:6)
没有这种方法行不通。参数specimen
已经衰减为指针类型(或者甚至可能一直都是指针)。 std::is_array
使用的元编程技术不会以某种方式追溯到调用者。
此外,您正在(无意间)测试T
而不是T*
-但更改为后者将无效。
答案 1 :(得分:4)
如何判断指针是否为数组的指针?
指针具有类型,指示其指向的内容。当它指向数组时,指针的类型就会反映出来,例如:
int arr[2][2] = {{1,2},{3,4}};
auto x = &arr[0];
x
的类型为int(*)[2]
-指向2个int
的数组的指针,在这种情况下为{1,2}
。如果将此指针增加1,它将指向2个int
的下一个数组,即{3,4}
。如果将此指针传递给函数,则T将推导为int[2]
,结果将为true
;
对于一维数组,没有什么不同
int arr[4] = {1,2,3,4};
auto x = &arr;
x
类型将是int(*)[4]
,它也将起作用,并且该函数将返回true
。
但是,如果您将数组传递给函数而不是指针,从而迫使它衰减到指向其第一个元素的指针,则数组信息会丢失,因为指针现在的类型为int
。
auto x = arr;
x
的类型为int *
,它不指向数组,它指向第一个int
,即1
。如果将其增加一,它将指向下一个int
,依此类推。如果这是指向数组的指针,则将其加1时将指向数组末尾的下一个字节。将此指针传递给函数将返回2
,因为false
类型不是数组。
因此,要回答您的问题,您可以说出该指针是指向数组的指针,因为该信息将以指针类型提供。
int
int iam[3][3][3][3][3]{};
// returns true
auto is_array_2 = found_to_be_array(iam);
衰减到指向其第一个元素的指针,基本上,您正在测试iam
是否为数组,数组是否正确,因此可以正常工作。
答案 2 :(得分:1)
总是回答也许。是否非空数据指针指向数组元素。
为什么问?
该语言明确允许您将任何对象都视为一个对象数组的单个元素。当您需要序列,想要复制琐碎的对象等时,这真是太好了。
因此,每个指针都是以下之一:
虽然您可以区分情况1和2或3,但其余情况则需要分析该程序当前运行的完整历史记录。
答案 3 :(得分:0)
您对无法更改功能的要求很奇怪/不合理。
如果您不能更改函数签名,则无法检测到参数的产生方式(从ptr或数组),因为该信息丢失了。