Циклическая ссылка для typedef указателя функции в C

Я хотел бы определить хеш-таблицу с заменяемой хеш-функцией. Хеш-функция будет принимать указатель на хеш-таблицу и ключ для хеширования, возвращая целое число следующим образом:

typedef int (hash_function_t) (hashtable *, int);

где хеш-таблица хранит указатель на функцию, которая будет использоваться для хеширования ключей:

typedef struct ht {
  size_t size;
  ...
  hash_function_t *hash_function;
} hashtable;

К сожалению, это создает циклическую ссылку.

Мне нужен указатель на хеш-таблицу в определении хеш-функции, поэтому я могу сделать модуль по размеру хэш-таблицы, чтобы он не превышал максимальное количество сегментов. Мне нужна хеш-функция в хеш-таблице, чтобы мне не приходилось передавать указатель хеш-функции повсюду.

Я понимаю, что это приведет к коду вроде:

*ht->hash_function (ht, key)

что немного странно, но я в порядке с этим.

Помещение typedefs в любом порядке не работает. Должен ли я использовать длинное определение в хеш-таблице, а затем выполнять typedef, или есть лучший способ?

Все это предназначено для прямого C, а не для C++. Предпочтительны решения ANSI C!


person majelbstoat    schedule 11.12.2010    source источник


Ответы (1)


Вы можете объявить структуру, прежде чем использовать ее в определении. Это говорит компилятору, что структура существует, но она будет полностью определена позже. Что-то вроде этого:

/* declare it first */
struct ht;

typedef int (hash_function_t) (struct ht *, int);

typedef struct ht {
  size_t size;
  ...
  hash_function_t *hash_function;
} hashtable;
person Martin Kosek    schedule 11.12.2010
comment
Ха! Красиво и просто. Не знал, что вы можете объявить, а затем «повторно объявить» структуру. Большое спасибо! - person majelbstoat; 11.12.2010
comment
Теперь ты! :-) У меня была такая же проблема, когда я изучал C и реализовал связанные списки... - person Martin Kosek; 11.12.2010