Я сделал намного больше программирования на С++, чем программирование "простого старого С". Одна вещь, которую я очень скучаю, когда программирование в простой C - это типовые структуры данных, которые предоставляются в С++ с помощью шаблонов.
Для конкретности рассмотрим общий список, связанный отдельно. В С++ просто определить свой собственный класс шаблонов, а затем создать его для типов, которые вам нужны.
В C я могу придумать несколько способов реализации общего одноуровневого списка:
- Напишите тип связанного списка и поддерживающие процедуры один раз, используя указатели void, чтобы обойти систему типов.
- Записывать макросы препроцессора с требуемыми именами типов и т.д., чтобы генерировать версию структуры данных и поддерживающие процедуры типа.
- Используйте более сложный автономный инструмент для генерации кода для типов, которые вам нужны.
Мне не нравится вариант 1, так как он подрывает систему типов и, вероятно, будет иметь худшую производительность, чем специализированная реализация типа. Использование единообразного представления структуры данных для всех типов и отбрасывание в/из указателей void, насколько я вижу, требует наличия косвенности, которой будет избегать реализация, специализированная для типа элемента.
Вариант 2 не требует каких-либо дополнительных инструментов, но он чувствует себя несколько неуклюже и может давать плохие ошибки компилятора при неправильном использовании.
Вариант 3 может дать лучшие сообщения об ошибках компилятора, чем вариант 2, поскольку специализированный код структуры данных будет находиться в расширенной форме, которая может быть открыта в редакторе и проверена программистом (в отличие от кода, созданного макросами препроцессора). Однако этот вариант - самый тяжеловесный, своего рода "плохой шаблон". Я использовал этот подход раньше, используя простой sed script, чтобы специализировать "templated" версию некоторого кода C.
Я хотел бы запрограммировать мои будущие "низкоуровневые" проекты на C, а не на С++, но был напуган мыслью переписать общие структуры данных для каждого конкретного типа.
Какой у людей опыт с этой проблемой? Существуют ли хорошие библиотеки общих структур данных и алгоритмов в C, которые не идут с Вариантом 1 (то есть литье в и из указателей void, которое жертвует безопасностью типа и добавляет уровень косвенности)?