13

C 数组在 C++ 中的语法上有些难以理解,可能需要一些时间来适应。虽然一维数组衰减为指针:

void fn1(int x[2]) {}
void fn2(int*x) {}

fn1()fn2()具有相同的功能签名。

数组实际上确实具有包含数组中有多少元素的类型。如:

void fn(int (&)[2]) {}

fn()将只接受一个 2 元素 int 数组。

问题是,我只能看到固定数量的元素的数组只能由堆栈、文件范围或具有该签名的结构/类分配生成:

int twoElementArray[2];

如果我要在堆上动态分配它,我似乎无法获得相同的签名。我以为我可以投射它,但没有成功:

int (&array)[2] = reinterpret_cast<int(&)[2]>(new int[2]); // FAIL!

关于如何实现这一点的任何想法?

 


编辑:虽然我选择了一个答案,但它实际上并没有投射任何东西,而是使用了一种绝对比投射更好的方法(如果不需要 IMO,最好不要投射)。然而,它在技术上并没有回答这个问题,因为问题询问是否有“一种将指针转换为数组类型的方法?” 答案是肯定的。

int (&array)[2] = *reinterpret_cast<int(*)[2]>(new int[2]); // SUCCESS!

请注意,我不一定建议这样做,但它确实回答了这个问题。如果我需要将指针转换为数组类型,那将是如何做到的。阅读选择的答案以获得更好的解决方案operator new[]

4

3 回答 3

10

如果我正确理解你的问题,你会想做这样的事情:

// allocate an array of one int[2] dynamically
// and store a pointer to it
int(*p)[2] = new int[1][2];

// now initialize a reference to it
int(&array)[2] = *p;

// delete the array once you no longer need it
delete[] p;
于 2013-06-23T08:34:32.790 回答
1

我想这就是你要找的。对于堆,二维数组int[M][N]衰减为int(*)[N]。要通过引用传递它,请取消引用它(见m下文):

#include <iostream>
using namespace std;

void func(int (&x)[2])
{
    cout << x[0] << ' ' << x[1] << endl;
}

int main()
{
    // on the heap
    auto m = new int[1][2];
    m[0][0] = 1; m[0][1] = 2;
    auto n = new int[1][3];
    n[0][0] = 4; n[0][1] = 5; n[0][2] = 6;

    // on the stack
    int o[2] = {7,8};
    int p[3] = {9,10};

    func(*m);
    //func(*n); // doesn't compile, wrong size
    func(o);
    //func(p); // doesn't compile, wrong size
}

输出:

1 2
7 8
于 2013-06-23T08:33:32.677 回答
-1

根据马克的回答,这可能会更好:

template <typename T>
void func(const T &x)
{
    cout << x[0] << ' ' << x[1] << endl;
}

唯一不好的想法是这段代码是有效的:

cout << x[3] << endl;
于 2013-06-23T10:02:06.260 回答