Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
1 / 1 / 0
Регистрация: 02.10.2021
Сообщений: 83

Можно ли создать указатель на функции разного типа?

31.07.2025, 14:46. Показов 5122. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Можно ли создать указатель на функции разного типа ?

Если бы все функции били простые или хотя бы одинакового параметра, то без проблем:
C++
1
void* (*Function) ();
... и вперёд
C++
1
Function ();
Но как создать указатель на разные функции:
1. Простая функция без приема аргументов и без возврата void Fun (void)
2. Функция с приемом аргументов, но без возврата void Fun (...)
3. Без аргументов но с возвратом ... Fun (void)
4. и то и то. ... Fun (...)

И как потом вызывать в нужный момент заданную функцию по указателю с нужными аргументами.
Без проблем создать 3 указателя (структурой или или россыпью - без разницы) на: 1. саму функцию, 2. Принимаемый аргумент, 3 - переменную, принимающую возврат функции.

Но вот только соединить всё вместе никак не получается, тем более если аргументы и возвращаемые значения разных типов. Нормально не работает.
Прошу помочь.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.07.2025, 14:46
Ответы с готовыми решениями:

Можно ли, используя указатель, а не указатель на указатель, обработать все элементы двумерного массива?
Можно ли, используя указатель, а не указатель на указатель, обработать все элементы двумерного...

Про указатель *, указатель на указатель **, и про new
#include "stdafx.h" class neuro { public: double *inputs; int inputs_count; ...

Как получить ссылку на указатель или указатель на указатель в массиве?
В процессе реализации сортировки пузырьком натолкнулся на такую проблему: как поменять значения...

9
Покинул чат.
1132 / 727 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
31.07.2025, 18:01
Цитата Сообщение от Mr McLaren Посмотреть сообщение
создать указатель на разные функции
вроде как нет.
но можно это:
C++
1
2
    auto &&ref=Fun;
    ref();
совместить с шаблонами...
(зачем такое понадобилось -из сабжа не понятно)
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
31.07.2025, 20:16
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Без проблем создать 3 указателя (структурой или или россыпью - без разницы) на: 1. саму функцию, 2. Принимаемый аргумент, 3 - переменную, принимающую возврат функции.
При таком подходе такой набор не будет вести себя как указатель на функцию.
Ибо всё уже заранее привязано.

В чём практический смысл?
0
1 / 1 / 0
Регистрация: 02.10.2021
Сообщений: 83
31.07.2025, 21:27  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
В чём практический смысл?
Цитата Сообщение от sdf45 Посмотреть сообщение
зачем такое понадобилось -из сабжа не понятно
Ну я как бы ожидал что будут вопросы типа "зачем тебе это надо", но дабы не захламлять суть сабжа и не забивать моск, решил пока не делать этого заранее.

Смысл в следующем.
Допустим есть какой то драйвер на устройство, у которого есть набор различных функций. Функции могут быть абсолютно разные как я описал в 1 посту.
Согласно алгоритму основной программы нужно выполнить какую то функцию. Но если её на данный момент выполнить нельзя, например если шина занята, то приходится выполнение этой функции отложить. И при этом пометить параметры выполнения функции (функцию, аргументы, возвращаемое значение). Т. е. создать указатели (ссылки) на то что нужно выполнить в дальнейшем (некий callback), что передать (если нужно) и во что возвращать результат (если нужно). И когда появится возможность выполнить эту функцию, система все эти параметры знала.
Понимаю, что такого 100%-ного универсального способа нет, поэтому хочу найти альтернативные решения.
1-е альтернативное решение что пришло в голову (и оно сейчас работает) - создать доп. переменную, просто обозначающую условный номер действия и switch-ом уже расписывать инструкции. И когда пришла пора выполнить то, что мы хотели, - выполнять. Например:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
if (exe_num)
{
  switch (exe_num)
  {
  case 1: Fun1 (); break;
  case 2: Fun2 (arg); break;
  case 3: ret_var1 = Fun3 (); break;
  case 4: ret_var2 = Fun4 (&arg_ref); break;
  // и т. д.
  default: break;
  }
  exe_num = 0;  // Сброс запроса
}
Но по мне это получился какой то бред. Ну допустим это всё хорошо, если функций 2-3, а если пару десятков? Получается нехилая функция, расписывающая алгоритм действий работы с нужными функциями, а самое главное - путаница.
Если ли какие способы лучше?
0
1476 / 490 / 73
Регистрация: 22.09.2023
Сообщений: 1,505
01.08.2025, 00:33
Я бы делал как-то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class executor
{
public:
    void execute() = 0;
};
 
class fun1 : public executor
{
public:
    fun1();
    
    void execute() override     { Fun1(); }
};
 
class fun2 : public executor
{
public:
    fun2(int arg)
    : Arg(arg)
    {}
    
    void execute() override     { Fun2(Arg); }
private:
    int const Arg;
};
 
 
void test()
{
    if(!busy())
        Fun1();
    else
        Queue.push(new fun1);
    int Arg = 123;
    if(!busy())
        Fun2(Arg);
    else
        Queue.push(new fun2(Arg));
}
 
void process_queue()
{
    for(;;)
    {
        executor * To_do = Queue.pop();
        if(!To_do)
            break;
        To_do.execute();
    }
}
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
01.08.2025, 00:51
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Т. е. создать указатели (ссылки) на то что нужно выполнить в дальнейшем (некий callback), что передать (если нужно) и во что возвращать результат (если нужно). И когда появится возможность выполнить эту функцию, система все эти параметры знала.
Если просто выполнить, то можно через полиморфизм с шаблонами.
Но до конца не понятно всё равно.

Шаблоны ещё нужно подтягивать, пока криво/косо.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <functional>
#include <vector>
#include <memory>
 
void foo(){std::cout << "foo" << std::endl;}
bool bar(const char*){return static_cast<bool>(std::cout << "bar" << std::endl);}
 
struct BaseCaller{
   virtual void Call() = 0;
   virtual ~BaseCaller() = default;
};
 
template< class Func, class Result, class... Args>
struct BindedFunctionWithResult : BaseCaller{
   BindedFunctionWithResult(Func&& f, Result& res, Args&&... args)
      :func{std::bind(std::forward<Func>(f), std::forward<Args>(args)...)},
       res{res}{
   }
   virtual void Call(){
      res = func();
   }
protected:
   std::function<Result()> func;
   Result& res;
};
 
template<class Func, class... Args>
struct BindedFunctionWithResult<Func, void, Args...> : BaseCaller{
   BindedFunctionWithResult(Func&& f, Args&&... args)
      :func{std::bind(std::forward<Func>(f), std::forward<Args>(args)...)}{
   }
   virtual void Call(){
      func();
   }
protected:
   std::function<void()> func;
};
 
template<class Func, class... Args>
struct BindedFunction : BindedFunctionWithResult<Func, std::invoke_result_t<Func, Args...>, Args...> {
   using BindedFunctionWithResult<Func, std::invoke_result_t<Func, Args...>, Args...>::BindedFunctionWithResult;
};
 
int main(){
   /*
   BindedFunction<decltype(foo)> b1(foo);
   ((BaseCaller*)(&b1))->Call();
 
   bool res = false;
   BindedFunction<decltype(bar), const char*> b2(bar, res, "Hello World");
   ((BaseCaller*)(&b2))->Call();
   std::cout << res << std::endl;
   */
 
   bool res = false;
   std::vector<std::unique_ptr<BaseCaller>> vf;
   vf.push_back(std::unique_ptr<BaseCaller>(new BindedFunction<decltype(foo)>(foo)));
   vf.push_back(std::unique_ptr<BaseCaller>(new BindedFunction<decltype(bar), const char*>(bar, res, "Hello World")));
 
   vf[0]->Call();
   vf[1]->Call();
   std::cout << res << std::endl;
}
0
 Аватар для volodin661
6793 / 2290 / 348
Регистрация: 10.12.2013
Сообщений: 7,901
01.08.2025, 10:27
я и думать не стал, просто спросил: c++ function signatures dispatcher
ИИ ответил вполне толково.
0
01.08.2025, 13:18

Не по теме:

Цитата Сообщение от volodin661 Посмотреть сообщение
ИИ ответил вполне толково.
Уже заработал свой первый миллион с помощью толкового "ИИ"(хотя это ни какой не ИИ)?
Ну хорошо хоть не скопипастил сюда его генерацию.

0
112 / 110 / 30
Регистрация: 08.05.2021
Сообщений: 485
03.08.2025, 09:17
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Но по мне это получился какой то бред. Ну допустим это всё хорошо, если функций 2-3, а если пару десятков? Получается нехилая функция, расписывающая алгоритм действий работы с нужными функциями, а самое главное - путаница.
Если ли какие способы лучше?
У тебя есть типы и логика на них. Просто пишешь func(args) и язык сам тебе нужную функцию вызовет. Никаких ручных диспатчей/кейсов не нужно.
0
1969 / 825 / 115
Регистрация: 01.10.2012
Сообщений: 4,948
Записей в блоге: 2
03.08.2025, 19:21
Цитата Сообщение от Mr McLaren Посмотреть сообщение
Допустим есть какой то драйвер на устройство, у которого есть набор различных функций. Функции могут быть абсолютно разные как я описал в 1 посту.
Согласно алгоритму основной программы нужно выполнить какую то функцию. Но если её на данный момент выполнить нельзя, например если шина занята, то приходится выполнение этой функции отложить. И при этом пометить параметры выполнения функции (функцию, аргументы, возвращаемое значение). Т. е. создать указатели (ссылки) на то что нужно выполнить в дальнейшем (некий callback), что передать (если нужно) и во что возвращать результат (если нужно). И когда появится возможность выполнить эту функцию, система все эти параметры знала.
Это очень напоминает систему "слот/сигнал" в фреймворке Qt. Заметим что "под капотом" там - обычный/махровый switch который правда генерится автоматом. Сигналы могут помещаться в очередь событий, выполняться с задержкой и.т.п.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.08.2025, 19:21
Помогаю со студенческими работами здесь

А почему нельзя передавать в ф-ю добавления элемента в стек один указатель? Почему нужен именно указатель на указатель?
Вот код ф-ии добавления элемента в стек: void push1(Node **top, int d) { // top...

Нужен способ помещения разного рода типа данных в контейнеры типа массивов или структур
Сабж. Нужен способ помещения разного рода типа данных в контейнеры типа массивов или структур...

Не могу создать указатель на функцию. ошибка: нестандартный синтаксис; используйте "&", чтобы создать указатель на член
Выбивает ошибку, когда хочу присвоить переменной адрес какой то функции. Ошибка в строке 28(если...

Указатели и указатели на указатели, а также типы данных
Недавно начал изучать Си, перешел с Delphi. Много непонятного и пока процесс идет медленно....

Создать массив указателей на функции к функциям, которые имеют разное число и типы параметров?
Можно ли создать массив указателей на функции к функциям, которые имеют разное число и типы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru