Правильное использование ifdef для записи одной и той же функции для разных типов значений, не записывая ее более одного раза - PullRequest
0 голосов
/ 20 июня 2020

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

Я пытаюсь создать способ запуска функции в зависимости от того, с каким типом я сейчас работаю [int / float] без необходимости писать его дважды. так что я получил что-то вроде этого:

void addItemToTree(BST* bst, void* val) 
{
#ifdef IsInt
    addItemToTreeRec(bst->head, *((int*)val));
#else
    addItemToTreeRec(bst->head, *((float*)val));
#endif
}

пока никаких проблем, это приводит к:

#ifdef IsInt
void addItemToTreeRec(node* my_node, int val)
#else
void addItemToTreeRec(node* my_node, float val)
#endif
{
-- function itself ---
}

но проблема в том, заголовочный файл, содержащий все целые числа, связанные структура и объявление не распознают мою функцию, в то время как файл заголовка float распознает . Я подумал, что это должно что-то делать с тем, как я кладу ifdef, но я не могу решить его, не копируя весь код и не помещая его перед #else

1 Ответ

0 голосов
/ 20 июня 2020

Примечание: макросы препроцессора раскрывают перед компиляцией . Вы не можете изменять определение функции и вызывать разные версии функции во время выполнения.

Если это то, что вы все же ищете, вы можете использовать директивы #ifdef / #else в списке параметров, чтобы выбрать, какой тип должен быть вторым параметром, без фактического определения различных функций:

#define IsInt

void addItemToTreeRec (node* my_node,        // Function declaration addItemToTreeRec. 
#ifdef IsInt 
int 
#else
float 
#endif
val
);

void addItemToTreeRec (node* my_node,        // Function definition addItemToTreeRec.
#ifdef IsInt 
int 
#else
float 
#endif
val
)
{
    #ifdef IsInt
    // Code if val is of type int.
    #else
    // Code if val is of type float.
    #endif
}

void addItemToTree ( BST* bst,           // Function declaration addItemToTree.
#ifdef IsInt     
int 
#else            
float 
#endif 
val
);

void addItemToTree ( BST* bst,           // Function definition addItemToTree.
#ifdef IsInt     
int 
#else            
float
#endif 
val
)
{
    addItemToTreeRec (bst->head, 
#ifdef IsInt
    *((int*)val)
#else
    *((float*)val)
#endif
    );
}

Примечание: это не обязательно, чтобы рассматривать его как следующий код. Вы можете перенести объявления в определенные файлы заголовков c, а также определения в разные исходные файлы, но addItemToTreeRec должен быть объявлен как минимум перед addItemToTree, потому что он используется в addItemToTree.

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