У меня очень ограниченный набор типов действительных чисел (в настоящее время float
и double
), на которые я использую sh все функции моей математической библиотеки, которые нужно использовать в качестве шаблона. Я ожидаю, что они будут объявлены в файлах заголовков:
template<typename R> void doA(task_t<R> t, ...);
template<typename R> void doB(task_t<R> t, ...);
template<typename R> void doC(task_t<R> t, ...);
реализовано в исходных файлах:
template<typename R> void doA(task_t<R> t, ...) { ... }
template<typename R> void doB(task_t<R> t, ...) { ... }
template<typename R> void doC(task_t<R> t, ...) { ... }
и явно инициализировано в этих исходных файлах:
template void doA(task_t<float> t, ...);
template void doB(task_t<float> t, ...);
template void doC(task_t<float> t, ...);
template void doA(task_t<double> t, ...);
template void doB(task_t<double> t, ...);
template void doC(task_t<double> t, ...);
Кроме того, подмножество из них должно быть предложено через C -совместимый заголовок:
#ifdef __cplusplus
using taskr32_t = task_t<float>;
using taskr64_t = task_t<double>;
#else
typedef struct taskr32t *taskr32_t;
typedef struct taskr64t *taskr64_t;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void doAr32(taskr32_t t, ...);
void doBr32(taskr32_t t, ...);
void doAr64(taskr64_t t, ...);
void doBr64(taskr64_t t, ...);
#ifdef __cplusplus
}
#endif
, который я даю простейшую возможную реализацию пересылки C ++:
void doAr32(taskr32_t t, ...) { doA<float>(t, ...) };
void doBr32(taskr32_t t, ...) { doB<float>(t, ...) };
void doAr64(taskr64_t t, ...) { doA<double>(t, ...) };
void doBr64(taskr64_t t, ...) { doB<double>(t, ...) };
То есть уже 8 повторений полного doA
объявления функции. Мой вопрос в том, как уменьшить количество повторений и получить более чистый код с меньшим набором текста? Например, возможно ли выполнить явную инициализацию без повторения полного объявления?
Я знаю, что многие предпочитают помещать реализации шаблонных функций непосредственно в файлы заголовков, чтобы избежать как прямого объявления, так и явной инициализации, но есть аргументы против :
- Я точно знаю, какие типы поддерживаю, и набор очень ограничен.
- Время компиляции увеличивается (особенно инкрементальные компиляции мелких изменений).
- Зависимости ( doA зависит от doB и т. д.) становится труднее поддерживать без предварительных объявлений.
Моя лучшая идея до сих пор - просто сгенерировать код, касающийся явного создания экземпляра и C -совместимого уровня, который находится там, где все надоедливые повторы случаются. Это обычное / хорошо известное решение этой проблемы?