Использование типа _Generic в C для перегрузки функций во вложенной структуре - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь реализовать родительскую структуру с похожими функциями (разными параметрами) и двумя или более дочерними структурами в качестве членов.Девиз - реализовать такую ​​ситуацию, когда я могу вызвать функцию с тем же именем и, в зависимости от ее аргументов (тип структуры), вызывать связанную функцию-член.

Когда я пытаюсь реализовать это следующим образом, компилятор gcc выдает ошибку, утверждая, что идентификатор, указанный в _Generic, неверен.Итак, какой будет правильный идентификатор для использования?Как исправить эту ошибку!

PS: эта программа на самом деле является прототипом более крупной программы, которую я реализую.Следовательно, он предназначен только для прояснения моей актуальной проблемы.

Спасибо.

КОД C:

#include<stdio.h>
#include<stdlib.h>

typedef struct myint{
         int mem;
}INT;

typedef struct mydouble{
      double mem;
}DOUBLE;

typedef struct head{
    INT *integer;
    DOUBLE *d_precision;
    int (*x)(INT *p);
    double (*xf)(DOUBLE *u);
}H;

int x(INT *p){
    p->mem= 2;
    return p->mem*p->mem;
}

double xf(DOUBLE *u){
    u->mem= 2.2;
    return u->mem*u->mem;
}

#define x(a) _Generic(a, struct myint*: x, DOUBLE*: xf)(a)

int main(void){
    H *ptr = (H *)malloc(sizeof(H));

    INT *i = (INT *)malloc(sizeof(INT));
    ptr->integer = i; 
    DOUBLE *f = (DOUBLE *)malloc(sizeof(INT));
    ptr->d_precision = f;

    printf("%d", (*ptr).x(ptr->d_precision));
    printf("%f", (*ptr).x(ptr->integer));

    return 0;
}

==============================================================================ВЫХОД КОМПИЛЕРА:

root@kali:~# gcc -std=c11 -o generic3 generic3.c
generic3.c: In function ‘main’:
generic3.c:30:14: error: expected identifier before ‘_Generic’
 #define x(a) _Generic(a, struct myint*: x, DOUBLE *: xf)(a)
              ^~~~~~~~
generic3.c:40:22: note: in expansion of macro ‘x’
  printf("%d", (*ptr).x(ptr->d_precision));
                      ^
generic3.c:30:14: error: expected identifier before ‘_Generic’
 #define x(a) _Generic(a, struct myint*: x, DOUBLE *: xf)(a)
              ^~~~~~~~
generic3.c:41:22: note: in expansion of macro ‘x’
  printf("%f", (*ptr).x(ptr->integer));

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Удалить префикс (*p)..Это C, а не C ++.

0 голосов
/ 03 декабря 2018

Чтение ссылки для _Generic, похоже, что вторым параметром является список выражений , а не произвольных последовательностей токенов.
В вашем случае, _Genericобрабатывается на уровне компилятора, когда предварительно обработанный исходный код уже должен быть синтаксически допустимым, что не является:

printf("%d", (*ptr)._Generic(ptr->d_precision, struct myint*: x, double: xf)(ptr->d_precision));
//                 ^^^^^^^^^ ???
...