2016-04-09 2 views
0

Я пишу на C и хотел бы иметь некоторую реализацию переменных типа. В Haskell, например, я мог бы написать что-то вроде:Внесите переменные типа в C

data Matrix a = Matrix [a] Int Int 

, который позволил бы мне определить матрицы с элементами любого типа «а». В C, я написал для каждого типа некоторую структуру:

struct zMatrix { 
    int dim_row; 
    int dim_col; 
    int *coords; 
}; 

struct rMatrix { 
    int dim_row; 
    int dim_col; 
    float *coords; 
}; 

... 

Есть ли какой-нибудь способ, чтобы иметь общую структуру матрицы и некоторые функции, чтобы создать матрицу, которая будет указывать тип поля COORDS? Что-то вроде:

struct matrix { 
    int dim_row; 
    int dim_col; 
    (typevar type) *coords; 
}; 

struct matrix matrixCreate(typevar type, int n, int m){...}; 
struct matrix M = matrixCreate(int, 3, 3); 
struct matric M = matrixCreate(float, 3, 3); 
... 
+6

У вас может быть 'void *' или 'union' нескольких типов. Хорошая идея - это другой вопрос. C не является Haskell, рассматривая его так, как если бы это было необычайно болезненно. – EOF

+1

Если у вас ограниченное количество типов 'a', вы также можете использовать макросы для генерации вариантов' int, float, ... 'для вас, не повторяя все. Функции можно сделать универсальными в безопасном типе, используя '_Generic'. Тем не менее, я думаю, что это не очень идиоматических в C, чтобы сделать это: вместо того, чтобы нажимать трудно достичь 100% типобезопасен интерфейс борется против простоты системы типа С (например, не параметрических типов), это больше распространено, чтобы выбрать для базовый вариант использования 'void *' и отбрасываний, даже если это не так безопасно для типов и повышает нагрузку на пользователя (что должно быть уверенным, что приводы будут в порядке). – chi

ответ

1

Вы можете это сделать. Как упоминалось в @EOF, вы можете использовать тип объединения для той части структуры, которая отличается для разных типов данных. Вероятно, вы захотите сохранить что-то, представляющее тип в структуре. Вы не можете передать имя типа функции, как в вашем примере, но вы можете определить перечисление, представляющее различные типы. Затем вы должны использовать инструкции switch для реализации любого кода, специфичного для конкретного типа. Альтернативой использованию операторов switch является использование структуры данных, которая описывает тип (это будет содержать указатели на функции и, возможно, другую информацию). Вы объявляете экземпляр этой структуры данных для каждого типа, а ваш код типа должен использовать информацию в структуре данных соответствующего типа, чтобы делать то, что ему нужно. Структуры данных типа могут быть в массиве, который вы должны индексировать с помощью значения перечисления типа, или вы можете использовать указатель на структуру данных типа для представления типа.

Если C++ - это вариант, это значительно упростит работу.

Смежные вопросы