Перегрузка функции с помощью void

Попытка перегрузить функцию на языке программирования C с помощью _Generic. Нашел примеры:

Это пример:

#include <stdio.h>
#include <math.h>

void display_float(float dispid) ;
void display_int(int dispid) ;
void display_void(void) ;

#define display(x) _Generic((x), \
          float: display_float, \
          int: display_int,  \
          default: display_float  \
)(x)

void display_void(void){
    printf("display id: 0\n") ;
}

void display_float(float dispid){
   printf("display id: %f\n", dispid) ;
}

void display_int(int dispid){
    printf("display id: %d\n", dispid) ;
}

void main(void){

    display(5) ;
    display(6.5) ;
}

Теперь я также хочу перегрузить функцию с помощью display(). Это означает, что функция будет принимать void, вызывать функцию display_void() и отображать 0. Кажется, не может этого сделать. Любая помощь будет оценена по достоинству.

РЕДАКТИРОВАТЬ 1:

Также см. примеры здесь. Один из примеров (я думаю) — это передача указателя на пустоту. Можно ли это реализовать?

Вы не можете перегрузить отсутствие параметра. Ваш выбор display_float по умолчанию в _Generic удивителен, но изменение его на display_void мало поможет; вам нужно будет предоставить аргумент макросу display, и он будет передан любой функции в предложении default, и если бы это был display_void, он не ожидал бы никаких аргументов. Однако _Generic ожидает выражение-присваивания в качестве первого аргумента, и ни пустая последовательность токенов, ни () не приемлемы в качестве выражение-присваивания, поэтому вы не можете использовать _Generic для перегрузки ().

Jonathan Leffler 28.05.2019 05:50

@JonathanLeffler: я подозревал это. Но также см. мой РЕДАКТИРОВАТЬ 1 в вопросе.

ASarkar 28.05.2019 06:00

Передавать указатель на void легко — да, с этим можно справиться. Он не передает ничего сложного (я думаю, что это невозможно сделать, даже если C11 разрешает макросам пустые аргументы).

Jonathan Leffler 28.05.2019 06:01

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

StoryTeller - Unslander Monica 28.05.2019 07:08

Без лучших примеров (или какого-то подлинного минимальный воспроизводимый пример в самом вашем вопросе) вопрос неясен, и я проголосовал за его закрытие.

Basile Starynkevitch 28.05.2019 08:07
void main(void) должно быть int main(void).
Keith Thompson 28.05.2019 08:23

Вы можете определить макрос display0, который не принимает аргументов, и макрос display1, принимающий один аргумент. Когда вы пишете вызов, вы знаете, сколько аргументов вы передаете, поэтому выбор макроса для вызова не является большой проблемой.

Keith Thompson 28.05.2019 08:24

@BasileStarynkevitch: воспроизводимый пример приведен в самом вопросе. Не уверен, что еще вы просите. Все остальные, кажется, прекрасно понимают, в чем вопрос.

ASarkar 28.05.2019 09:13

Поскольку я ответил речь идет не о перегрузке функций, то, по крайней мере, заголовок вопроса неверен, и, по крайней мере, это следует исправить; а _Generic должен даже намекать не на перегрузку, а на универсальность

Basile Starynkevitch 28.05.2019 09:14

Оригинальное название было отредактировано кем-то другим. Кроме того, ссылка, которую я дал в самом начале, показывает, что перегрузку функций в C можно выполнить с помощью _Generic.

ASarkar 28.05.2019 09:21

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

Basile Starynkevitch 28.05.2019 09:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
11
1 103
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Trying to overloading a function in C programming language

С11 не содержит перегрузка функций и _Generic для универсальность, нет для перегрузки, проверьте это, прочитав n1570. Рассмотрите возможность перехода на C++ (или, что еще лучше, на Ржавчина), который обеспечивает перегрузку функций. Обратите внимание, что использование аргумента void (не void*, просто void) для функции C является незаконным, поэтому в C нет супертипа "верх", который был бы супертипом других типов (и это из-за соглашения о вызовах и АБИ соображений, делающих C языком программирования низкий уровень, иногда даже называемым «ассемблером портативный»). Узнайте больше о абстрактная интерпретация и системы типов, пожалуйста.

Если бы _Generic означало перегрузку, члены комитета по стандарту C11 — все эксперты по языкам программирования и достаточно хорошие англоязычные писатели — назвали бы его как _Overload, но они поступили так мудро.

Пища для размышлений (при условии, что и stderr, и stdin работают так, как вы хотите, чтобы они работали) :
а как насчет некоторых гипотетических display(stderr) или display(*stdin) или display("abc") ?

(a wrong suggestion below, followed by a better advice)

плохой подход

(это не работает!)

Ваш display_void должен иметь какой-то аргумент, например.

void display_void(void*p) { printf("p@%p\n", p);

Тогда у вас может быть:

#define display_anything(P) display_void((void*)(&(P)))

с участием

#define display(x) _Generic((x), \
      float: display_float, \
      int: display_int,  \
      default: display_anything  \
)(x)

лучший совет

Так как это не работает (и не работает), спроектируйте свой код каким-то другим способом. Например, рассмотрите возможность наличия некоторого помеченный союз, например здесь. Посмотрите на реализацию GВариант (от Glib) для вдохновения.

Пожалуйста, посмотрите мой РЕДАКТИРОВАТЬ 2.

ASarkar 28.05.2019 06:32

Увидел, одобрил ее развертывание, дал получше совет.

Basile Starynkevitch 28.05.2019 07:17
Ответ принят как подходящий

Конечно. Перегрузить макрос по количеству аргументов.

void display_float(float dispid) ;
void display_int(int dispid) ;
void display_void(void) ;

#define _display_1(x) _Generic((x), \
          float: display_float, \
          int: display_int,  \
          default: display_float  \
)(x)
#define _display_0()  display_void()
#define _display_N(_0,_1,N,...)  _display_ ## N
#define display(...) _display_N(_0,##__VA_ARGS__,1,0)(__VA_ARGS__)

int main() {
    display();
    display(1);
    display(1.1);
}

Проверено на божественная стрела.

Обратите внимание, что , ##__VA_ARGS__ — это расширение gcc, не описанный в стандарте C.

Не будет хорошо работать с display(stderr); или FILE* f = fopen(__FILE__, "r"); display(f); или в Linux с использованием стат(2) с struct stat st; stat("/dev/zero", &st);, за которым следует display(st); или display(&st); пожалуйста, улучшите свой ответ для display(stderr)

Basile Starynkevitch 28.05.2019 07:55

@BasileStarynkevitch Я не понимаю твоей точки зрения. Нет ни display(FILE*), ни display(struct stat*), ни display(struct stat) перегрузок, поэтому они не должны работать. Я не понимаю вашей точки зрения. Если вы добавите их, они будут работать. Почему display(stderr) должно работать? ОП этого не просил. Я не буду.

KamilCuk 28.05.2019 07:59

ОП мечтает о вещи общийdisplay, и я пытаюсь объяснить (извините, я не носитель английского языка), что такая вещь не может существовать (если только ОП не определит display_FILEявно и display_stat, чего он не хочет!)

Basile Starynkevitch 28.05.2019 08:01

@BasileStarynkevitch ? Now I also want to overload the function with display(). Meaning the function would intake a void, call the function display_void() - это очень конкретно. Мы хотим написать display() и заставить его звонить display_void(). Ни больше ни меньше. Я не знаю ОП настолько хорошо, чтобы угадывать, о чем она / он мечтает и делает или не хочет. В посте ОП около 6 правок, возможно, ваш браузер мог его испортить.

KamilCuk 28.05.2019 08:08

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

Basile Starynkevitch 28.05.2019 08:37

Другие вопросы по теме