[C++] "Шаблонизация" внешного C API
{
T frob1(...);
T frob2(...);
T frob3(...);
};
заимплементить специализации через перевызов и юзать frob
Вы пишете шаблонную функцию template<typename T> void fooну такие функции обычно не пишут
обычно такие стратегии оформляются в виде traits (хотя я изначальную задачу не понял, так что телепатирую)
Однако при таком подходе требуется несколько раз повторить плохо автоматизируемые действия: в месте специализации нужно будет добавить имена аргументов в список параметров новых функций, а потом повторить их при вызове оригинальной библиотечной функции. Нет ли способа подсократить этот механический ручной труд?
#define FROB(T) T frob(T ....) { frob##T(...); }
Представь, что библиотека из условия это blas или fftw3, а функция foo их использует. Так понятно?
Однако при таком подходе требуется несколько раз повторить плохо автоматизируемые действия: в месте специализации нужно будет добавить имена аргументов в список параметров новых функций, а потом повторить их при вызове оригинальной библиотечной функции. Нет ли способа подсократить этот механический ручной труд?если C API нетолстое, то проще один раз руками записать. что там автоматизировать? если хочется толстое API завраппить C++, то можно и кодогенерацией заморочиться. это кстати не так сложно как многие себе представляют
либо, как выше предложили, макросами заминировать код
Представь, что библиотека из условия это blas или fftw3, а функция foo их использует. Так понятно?Ты не поверишь, все равно traits.
Умными словами все горазды трындеть. Ты код покажи!
template<typename> struct Frob {
};
#define COMMA ,
#define FROB(num, type, Type, args, decls) \
static type frob ## num(type *v decls) { \
return frob ## num ## Type(v args); \
}
#define DEF_FROB(type, Type) \
template<> struct Frob<type> { \
FROB(1, type, Type \
FROB(2, type, Type, COMMA i1, COMMA int i1) \
FROB(3, type, Type, COMMA i1 COMMA i2, COMMA int i1 COMMA int i2) \
}
DEF_FROB(double, Double);
DEF_FROB(float, Float);
#undef DEF_FROB
#undef FROB
Ты сам попросил.
Кстати, необходимость дублировать название типа с заглавной буквы иногда заставляет меня думать о благости подчеркиваний...
Кстати, необходимость дублировать название типа с заглавной буквы иногда заставляет меня думать о благости подчеркиваний...тебе нужно заставлять себя еще больше думать
В условии списки аргументов разные везде, а не (type*). Как и в приведённых примерах (fftw3, blas).
Да на!
Я боюсь возгорания опилок!
всех бы и вычислили
template<class T> struct frob
{
typedef T (* const frob1_tT*);
typedef T (* const frob2_tT*, int);
typedef T (* const frob3_tT*, int, int);
static frob1_t frob1;
static frob2_t frob2;
static frob3_t frob3;
};
#define FROB_DECL(type, field, value) \
template<> frob<type>::field##_t frob<type>::field = value;
FROB_DECL(float, frob1, frob1Float)
FROB_DECL(float, frob2, frob2Float)
FROB_DECL(float, frob3, frob3Float)
FROB_DECL(double, frob1, frob1Double)
FROB_DECL(double, frob2, frob2Double)
FROB_DECL(double, frob3, frob3Double)
Type mismatch ведь, нет?
Где? Всё компилится.
шаблон, в котором вся шаблонность — статический указатель, делает мой мозг скучать.
Вот примерно такую загогулину я имел в виду, когда писал исходный пост.хорошая загогулина
Оставить комментарий
procenkotanya
Допустим, вы используете сишную библиотеку с подобным API:Вы пишете шаблонную функцию template<typename T> void foo в которой T может быть float или double, и в зависимости от Т foo должна вызывать соответствующую библиотечную функцию; если это важно, foo не очень короткая, и frob* там вызываются в нескольких разных местах. Ваши действия?