是否可以将动态分配的数组传递给需要数组引用的函数?
Is it possible to pass a dynamically allocated array to a function that requires an array reference?
预先说明:我知道按照我在这里的要求做并不是一个好主意。这只是出于病态的语言好奇而产生的问题,而不是来自实际使用。我在这里应用的规则完全是任意的。
假设我们有一个函数,其定义如下。它不能更改为除此之外的任何内容,不允许模板或函数重载。此功能的实现也必须不变(并且可以被视为未知)。然而,我们知道该参数用作输出参数。
void my_func(int (&arr)[10]);
在另一个函数中,我们动态分配一个数组。这个分配也不能改变,我们不允许在堆栈上分配。也不允许进一步分配。
int* my_arr = new int[10];
是否可以通过某种方式调用 my_func
并传递它 my_arr
?换句话说,是否有可能以某种方式欺骗类型系统将 my_arr
视为数组而不是指针?
天真的转换并不能解决问题,所有这些都会导致编译错误:
my_func((int[10])my_arr);
my_func(static_cast<int[10]>(my_arr));
my_func(reinterpret_cast<int[10]>(my_arr));
另一个注意事项:我想欺骗类型系统。我不想从堆栈数组等复制数据。为什么?再次:病态的好奇心。
并不是说我会推荐做任何此类事情...
#include <iostream>
void my_func(int (&arr)[10])
{
std::cout << "Address: " << &arr << std::endl;
for (int i=0; i<10; ++i)
std::cout << arr[i] << std::endl;
}
int main()
{
int *ptr=new int[10];
for (int i=0; i<10; ++i)
ptr[i]=i;
std::cout << "Pointer: " << ptr << std::endl;
my_func(*( int (*)[10])ptr);
return 0;
}
代替 C 风格的转换,reinterpret_cast
也应该有效。诀窍是首先获取指向数组的指针,然后取消引用它。瞧,对数组的引用。
您可以为此使用 reinterpret_cast
。使用数组类型的别名以使代码更易于阅读,您会得到类似以下内容的内容:
void my_func(int (&arr)[10])
{
for (auto e : arr)
std::cout << e << " ";
}
int main()
{
using array_t = int[10];
int* my_arr = new int[10]{1,2,3,4,5,6,7,8,9,10};
my_func(reinterpret_cast<array_t&>(*my_arr));
}
你可以看到在这个 live example 工作。
预先说明:我知道按照我在这里的要求做并不是一个好主意。这只是出于病态的语言好奇而产生的问题,而不是来自实际使用。我在这里应用的规则完全是任意的。
假设我们有一个函数,其定义如下。它不能更改为除此之外的任何内容,不允许模板或函数重载。此功能的实现也必须不变(并且可以被视为未知)。然而,我们知道该参数用作输出参数。
void my_func(int (&arr)[10]);
在另一个函数中,我们动态分配一个数组。这个分配也不能改变,我们不允许在堆栈上分配。也不允许进一步分配。
int* my_arr = new int[10];
是否可以通过某种方式调用 my_func
并传递它 my_arr
?换句话说,是否有可能以某种方式欺骗类型系统将 my_arr
视为数组而不是指针?
天真的转换并不能解决问题,所有这些都会导致编译错误:
my_func((int[10])my_arr);
my_func(static_cast<int[10]>(my_arr));
my_func(reinterpret_cast<int[10]>(my_arr));
另一个注意事项:我想欺骗类型系统。我不想从堆栈数组等复制数据。为什么?再次:病态的好奇心。
并不是说我会推荐做任何此类事情...
#include <iostream>
void my_func(int (&arr)[10])
{
std::cout << "Address: " << &arr << std::endl;
for (int i=0; i<10; ++i)
std::cout << arr[i] << std::endl;
}
int main()
{
int *ptr=new int[10];
for (int i=0; i<10; ++i)
ptr[i]=i;
std::cout << "Pointer: " << ptr << std::endl;
my_func(*( int (*)[10])ptr);
return 0;
}
代替 C 风格的转换,reinterpret_cast
也应该有效。诀窍是首先获取指向数组的指针,然后取消引用它。瞧,对数组的引用。
您可以为此使用 reinterpret_cast
。使用数组类型的别名以使代码更易于阅读,您会得到类似以下内容的内容:
void my_func(int (&arr)[10])
{
for (auto e : arr)
std::cout << e << " ";
}
int main()
{
using array_t = int[10];
int* my_arr = new int[10]{1,2,3,4,5,6,7,8,9,10};
my_func(reinterpret_cast<array_t&>(*my_arr));
}
你可以看到在这个 live example 工作。