2015-10-29 3 views
0

У меня возникла проблема с функцией, которая принимает указатель на фиксированный массив. У меня есть простой указатель, и компилятор не разрешит мне static_cast его к типу указателя к массиву.Как static_cast raw указатель на указатель-фиксированный массив

Вот пример кода: сообщение

int main() 
{ 
    typedef int (*Arr3)[3]; 

    int a[3] = {1,2,3}; 
    int* p = &a[0]; 

    Arr3 b = static_cast<Arr3>(p); 
} 

Ошибка:

prog.cpp:11:10: error: static_cast from 'int *' to 'Arr3' (aka 'int (*)[3]') is not allowed 
Arr3 b = static_cast<Arr3>(p); 
     ^~~~~~~~~~~~~~~~~~~~ 
1 error generated. 

Я уверен, что я мог бы использовать reinterpret_cast, но это действительно мой единственный вариант здесь? Или я чего-то не хватает?

+1

Я могу ошибаться, но не Arr3 а ** типа? IE указатель на массив, который распадается на указатель? Хотя p - это просто указатель на первый элемент массива. –

+0

Возможно, вы захотите объяснить, что вы пытаетесь сделать, указатель на массив нельзя отбрасывать из указателя на его содержащийся тип. Не позволяйте факту, что массивы неявно преобразуются в указатель на их содержащийся тип при падении шляпы, путают вас, они не взаимозаменяемы. – user657267

+2

@DominicMcDonnell No. 'Arr3' является указателем на массив' int [3] '. Не происходит разложение массивов. – emlai

ответ

0

Я считаю, что ваш бросок неверен

Arr3 b = static_cast<Arr3>(p); 

должен быть

Arr3 b = static_cast<Arr3>(&a); 

В самом деле, бросок не нужен. Просто

Arr3 b = &a; 

сделаю.

+0

Я хочу, чтобы 'Arr3' был типом указателя на массив. – rlbond

+0

@rlbond, тогда я считаю, что строка 'Arr3 b = static_cast (p);' должна быть 'Arr3 b = static_cast (&p);' – GreatAndPowerfulOz

+1

Это не совсем так. Невозможно, чтобы 'int **' мог быть преобразуется в 'int (*) [3]'. – rlbond

-1

Одномерный массив совместим с указателем, но это не относится к многомерному массиву. Например,

int *p = (int*)1; 
int (*s)[3] = (int (*)[3])2; 
printf("%d,%d\n", sizeof(int*), sizeof(int (*)[3])); 
printf("%d,%d\n", ++p,++s); 

Выход:

8,8 
5,14 

Они оба типа указателя, так что их размер составляет 8 байт INT 64-битную машину. ++s, этот указатель массива будет продвигать 3 элемента, но ++p, p будет только продвигать 1 элемент. Когда мы объявляем массив указателей, мы должны указывать размер во всех измерениях, кроме 1-го измерения. Компилятор должен знать эту информацию для вычисления арифметической операции указателя.

0

Вы не можете точно static_cast здесь, но есть уловка, которая больше типобезопасный чем reinterpret_cast:

#include <iostream> 
using std::cout; 

typedef int (*arr3p)[3]; 
typedef int arr3[3]; 

inline arr3& to_arr3(arr3 p) 
{ 
    return *(arr3p)(p); 
} 

inline arr3p to_arr3p(arr3 p) 
{ 
    return (arr3p)(p); 
} 

int main() { 
    arr3 a = {1, 2, 3}; 
    int *p = &a[0]; 

    arr3p foo = &to_arr3(p); 
    cout << (*foo)[0] << ", "; 

    arr3p bar = to_arr3p(p); 
    cout << (*bar)[1] << ", "; 

    arr3& baz = to_arr3(p); 
    cout << baz[2] << std::endl; 

    return 0; 
}