Есть ли способ, чтобы один член структуры удерживал один из разных типов структуры? - PullRequest
0 голосов
/ 04 октября 2019

Я работаю над кодом, который записывает вывод в разные потоки / файлы в зависимости от того, какая функция семейства вызывается пользователем. Я пытаюсь сделать это как можно более кратко и не иметь тонны неиспользованной информации в структуре, которую я использую для вызова реальной функции записи. В настоящее время у меня есть базовая структура (это просто черновик):

typedef int (*Write_Out) (char *src, size_t len);

typedef struct  s_vas_info
{
    char **ret;
    int prev_size;
}               t_vas_info;

typedef struct  s_vd_info
{
    int fd;
}               t_vd_info;

typedef struct  s_vf_info
{
    FILE *fp;
}               t_vf_info;

typedef struct  s_vsn_info
{
    size_t size;
    char * restrict str;
}               t_vsn_info;

typedef struct  s_writer
{
    int curr;
    Write_Out ft_write;
}               t_writer;

Где Write_Out будет указывать на функцию, которая отправляет вывод в нужное место назначения, t_writer будет хранить всю информацию для этого идругие структуры используются при вызове соответствующей функции. Теперь мне бы очень хотелось, чтобы у типа s_writer был еще один член, содержащий один из других типов структуры (напрямую, если это возможно, я не собираюсь решать эту проблему с помощью указателей и приведений, если их вообще можно избежать). Я довольно новичок в этом, поэтому я не знаю, возможно ли это (с этими или другими типами данных). Любая помощь будет оценена!

Ответы [ 2 ]

2 голосов
/ 04 октября 2019

Для этого вы хотите, чтобы union.

A union был похож на struct за исключением того, что он содержит только один элемент, если его члены в любой момент времени.

typedef struct  s_writer
{
    int curr;
    Write_Out ft_write;
    int active;
    union {
        struct {
            char **vas_ret;
            int vas_prev_size;
        };    
        struct {
            int vd_fd;
        };    
        struct {
            FILE *vf_fp;
        };    
        struct {
            size_t vsn_size;
            char * restrict vsn_str;
        };    
    };
} t_writer;

Вы можете использовать поле active, чтобы определить, какое поле объединения содержит фактические данные. Также обратите внимание, что у объединения и его внутренних структур нет названия, поэтому к их членам можно обращаться напрямую как к членам t_writer;

2 голосов
/ 04 октября 2019

Да, вы можете, используя ключевое слово union.

Вы получите что-то подобное:


typedef struct  s_mystruct
{
    union
    {
        t_writer    writer;
        t_vsn_info  vsn_info;
        t_vf_info   vf_info;
        t_vd_info   vd_info;
        t_vas_info  vas_info;
    }               u_type;
}               t_mystruct;
...