Можно ли использовать макросы для имитации шаблонных функций C ++? - PullRequest
1 голос
/ 17 сентября 2010

У меня есть программа на C, в которой мне нужно создать целое семейство функций, которые имеют одинаковые подписи и тела и различаются только по своим типам.То, что я хотел бы сделать, это определить макрос, который генерирует все эти функции для меня, иначе я потрачу много времени на копирование и изменение оригинальных функций.Например, одна из функций, которые мне нужно сгенерировать, выглядит следующим образом:

<em>int</em> copy_key__sint_(void *key, void **args, int argc, void **out {<br> if ((*out = malloc(sizeof(<em>int</em>))) {<br> return 1;<br> } </p> <pre><code>**((_int_ **) out) = *((_int_ *) key); return 0;

}

Идея состоит в том, что я мог бы вызвать макрос, GENERATE_FUNCTIONS ("int", "sint") или что-то вроде этого, и пусть он генерирует эту функцию.Части, выделенные курсивом, - это то, что нужно подключить.

Возможно ли это?

Ответы [ 4 ]

2 голосов
/ 17 сентября 2010

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

#define DECLARE_MY_COPY_FUNCTION(TYPE, SUFFIX)              \
int copy_function_ ## SUFFIX(unsigned count, TYPE* arg)

#define DEFINE_MY_COPY_FUNCTION(TYPE, SUFFIX)               \
int copy_function_ ## SUFFIX(unsigned count, TYPE* arg) {   \
 /* do something with TYPE */                               \
 return whatever;                                           \
}

Затем вы можете использовать это для объявления функций в файле заголовка

DECLARE_MY_COPY_FUNCTION(unsigned, toto);
DECLARE_MY_COPY_FUNCTION(double, hui);

и определите их в файле .c:

DEFINE_MY_COPY_FUNCTION(unsigned, toto);
DEFINE_MY_COPY_FUNCTION(double, hui);

В этой версии, как указано здесь, вы можете получить предупреждения о лишних `; '.Но вы можете избавиться от них, добавив фиктивные объявления в макросах, как это

#define DEFINE_MY_COPY_FUNCTION(TYPE, SUFFIX)               \
int copy_function_ ## SUFFIX(unsigned count, TYPE* arg) {   \
 /* do something with TYPE */                               \
 return whatever;                                           \
}                                                           \
enum { dummy_enum_for_copy_function_ ## SUFFIX }
2 голосов
/ 17 сентября 2010

Попробуйте что-то вроде этого (я только что проверил компиляцию, но не результат в выполненной программе):

 #include "memory.h"

   #define COPY_KEY(type, name)                                 \
   type name(void *key, void **args, int argc, void **out) { \
      if (*out = malloc(sizeof(type))) {                     \
         return 1;                                           \
      }                                                      \
   **((type **) out) = *((type *) key);                      \
   return 0;                                                 \
   }                                                         \

COPY_KEY(int, copy_key_sint)

Подробнее об универсальном программировании на C читайте в этом блоге, содержащем несколько примеров , а также этой книге, в которой содержатся интересные решения проблемы для основных структур данных и алгоритма.

1 голос
/ 17 сентября 2010

Это должно работать. Чтобы создать copy_key_sint, используйте copy_key_ ## sint.

Если вы не можете заставить это работать с CPP, напишите небольшую программу на C, которая генерирует исходный файл на языке C.

0 голосов
/ 17 сентября 2010

Разве макрос, который просто берет sizeof(*key) и вызывает одну функцию, использующую memcpy, будет намного чище (меньше злоупотреблений препроцессором и раздуванием кода), чем создание новой функции для каждого типа, просто чтобы он мог выполнитьнативное задание, а не memcpy?

Я считаю, что вся проблема заключается в вашей попытке применить мышление C ++ к C. C имеет memcpy по очень веской причине.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...