Подтвердить что ты не робот

Есть ли способ наведения указателя на тип массива?

C-массивы несколько сложно понять синтаксически на С++ и могут немного привыкнуть. Хотя 1D-массив распадается на указатель:

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

fn1() и fn2() имеют одну и ту же сигнатуру функции.

У массива действительно есть тип, который включает в себя количество элементов в массиве. Как в:

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

fn() будет принимать только 2-элементный массив int.

Thing is, я могу только видеть, что массив фиксированного числа элементов может генерироваться только стекю, областью файлов или распределением структуры/класса с этой сигнатурой:

int twoElementArray[2];

Если бы я динамически выделял его в куче, я не мог бы получить одну и ту же подпись. Я думал, что смогу его бросить, но безуспешно:

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

Любые идеи относительно того, как это может быть выполнено, если вообще?

 


РЕДАКТИРОВАТЬ:. Хотя я выбрал ответ, он на самом деле ничего не делает, но использует определенно лучший метод, чем литье (лучше не бросать, если не требуется ИМО). Тем не менее, это технически не отвечает на вопрос, так как вопрос спрашивает, существует ли способ для указания указателя на тип массива? Ответ - да.

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

Заметьте, что я не обязательно рекомендую это делать, но он отвечает на вопрос. Если бы мне нужно было преобразовать указатель в тип массива, это было бы так, как это сделать. Прочтите выбранный ответ для лучшего решения при использовании operator new[].

4b9b3361

Ответ 1

Если я правильно понял вашу проблему, вы бы хотели сделать что-то вроде этого:

// 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;

Ответ 2

Я думаю, что это то, что вы ищете. Для кучи двумерный массив 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

Ответ 3

Основываясь на ответе Марка, это может быть лучше:

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

Единственное плохое мнение, что этот код действителен:

cout << x[3] << endl;