Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.90/69: Рейтинг темы: голосов - 69, средняя оценка - 4.90
0 / 0 / 1
Регистрация: 29.06.2016
Сообщений: 110

Функция, возвращающая указатель на функцию

25.02.2019, 21:59. Показов 13599. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, у меня есть универсальная ф-ия, которая возвращает указатель на одну из трёх ф-ий. Каждая из тех трёх функций по-своему преобразует одномерный массив. Я не могу до конца понять, как это всё должно работать. В main() я создаю указатель на одну из трёх функций, затем вызываю универс. ф-ию, которая должна вернуть указатель на функцию. Подскажите, как это правильно реализовать и может ли вызываться другая функция, когда мы возвращаем указатель на неё из универс. ф-ии?
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
#include <iostream>
#include <iomanip>
using namespace std;
 
 void *UniversalFunc(int *p_arr, int n, void *ptr)
{
    int sum = 0;
    
    for (int i = 1; i < n; i++)
        sum += p_arr[i];
 
    if (sum == p_arr[0])
        return ptr;
}
 
void Inversion(int *p_arr, int n) //одна из трёх ф-ий(остальные две подобные)
{
    int temp = n - 1;
 
    for (int i = 0; i < n/2; i++, temp--)
        swap(p_arr[i], p_arr[temp]);
}
 
int main()
{
    int size = 0;
 
    cin >> size;
 
    int *ptr_arr = new int[size];
 
    for (int i = 0; i < size; i++)
        cin >> ptr_arr[i];
 
    void(*ptr_fcn)(int*, int) = Inversion; //указатель на ф-ию
    
    UniversalFunc(ptr_arr, size, ptr_fcn); //вызов универс. ф-ии
 
    PrintArray(ptr_arr, size);
 
    delete[] ptr_arr;
 
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.02.2019, 21:59
Ответы с готовыми решениями:

Функция, возвращающая указатель на функцию
Всем привет, Мне нужно создать функцию, которая будет возвращает указатель на функцию. Я создам массив указателей на функцию, присвою...

Функция, возвращающая указатель
Добрый вечер. Требуется написать программу, содержащую структуру вида type1 *имя(type2); т.е. функцию, которая принимает аргумент типа...

Функция, возвращающая указатель
Здравствуйте. Пускай есть класс Some_type и массив такого класса. Можно ли функцией Some_type* some_name (some_type) заполнять массив,...

25
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
25.02.2019, 22:31
Fossil121, Ну указатель можно как-то так вернуть
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
 
void foo1(){
    cout << __FUNCSIG__ << endl;
}
 
void foo2(){
    cout << __FUNCSIG__ << endl;
}
 
void* uniFoo(int a) {
    if (a) return foo1;
    else return foo2;
}
 
int main() {
    void *f = uniFoo(1);
    reinterpret_cast<void(*)()>(f)();
    reinterpret_cast<void(*)()>(uniFoo(0))();
 
    return 0;
}
0
0 / 0 / 1
Регистрация: 29.06.2016
Сообщений: 110
25.02.2019, 22:35  [ТС]
Avaddon74, извините, не очень понимаю, что в main() происходит, если честно
0
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
25.02.2019, 22:41
Цитата Сообщение от Avaddon74 Посмотреть сообщение
reinterpret_cast<void(*)()>(uniFoo(0))() ;
Ужас то какой Использовать std::function не красивее будет? Например:
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
#include <iostream>
#include <functional>
 
using namespace std;
using MyFunctionPtr = function<int(int)>;
 
int foo(int x) {
    return x * 10;
}
 
int bar(int x) {
    return x + 10;
}
 
MyFunctionPtr getf(int n) {
    if (n % 2) {
        return foo;
    }
    else {
        return bar;
    }
}
 
int main() {
 
    int x = 2;
    cout << getf(1)(x) << endl;
    cout << getf(2)(x) << endl;
 
    return 0;
}
2
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
25.02.2019, 22:46
reinterpret_cast<void(*)()> приводит к типу указатель на функцию

Добавлено через 3 минуты
Цитата Сообщение от valen10 Посмотреть сообщение
Ужас то какой
Прежде чем юзать STL нужно понимать синтаксис языка, и что внутри происходит, я пытался это показать, может и коряво вышло, но сам сам учусь
0
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
25.02.2019, 22:51
Цитата Сообщение от Avaddon74 Посмотреть сообщение
Прежде чем юзать STL нужно понимать синтаксис языка, и что внутри происходит
Хорошо, можно и без STL На примере кода ТС, если никто не против.
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
#include <iostream>
#include <iomanip>
 
using namespace std;
typedef void (*FuncPtr)(int*, int);
 
FuncPtr UniversalFunc(int *p_arr, int n, FuncPtr ptr)
{
    int sum = 0;
 
    for (int i = 1; i < n; i++)
        sum += p_arr[i];
 
//    if (sum == p_arr[0])
        return ptr;
}
 
void Inversion(int *p_arr, int n) //одна из трёх ф-ий(остальные две подобные)
{
    int temp = n - 1;
 
    for (int i = 0; i < n/2; i++, temp--)
        swap(p_arr[i], p_arr[temp]);
}
 
int main()
{
    int size = 0;
    cin >> size;
    int *ptr_arr = new int[size];
 
    for (int i = 0; i < size; i++)
        cin >> ptr_arr[i];
 
    FuncPtr ptr_fcn = Inversion; //указатель на ф-ию
 
    UniversalFunc(ptr_arr, size, ptr_fcn); //вызов универс. ф-ии
 
    //PrintArray(ptr_arr, size);
 
    delete[] ptr_arr;
 
    return 0;
}
3
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
25.02.2019, 22:57
valen10, А я до этого не додумался
C++
1
2
3
typedef void (*FuncPtr)(int*, int);
 
FuncPtr UniversalFunc(int....
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
25.02.2019, 23:03
Цитата Сообщение от valen10 Посмотреть сообщение
C++
1
typedef void (*FuncPtr)(int*, int);
лучше так
C++
1
using FuncPtr = void(*)(int*, int);
2
0 / 0 / 1
Регистрация: 29.06.2016
Сообщений: 110
25.02.2019, 23:03  [ТС]
valen10, а когда мы возвращаем из ф-ии указатель на ф-ию, другая ф-ия не вызывается?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
25.02.2019, 23:06
или так
C++
1
using FuncPtr = std::add_pointer<void(int*, int)>::type;
1
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
25.02.2019, 23:10
Цитата Сообщение от Azazel-San Посмотреть сообщение
лучше так
Возможно. Никак не могу привыкнуть к новым фишкам.

Цитата Сообщение от Fossil121 Посмотреть сообщение
а когда мы возвращаем из ф-ии указатель на ф-ию, другая ф-ия не вызывается?
Нет, если не вызвать ее специально. Для ее вызова необходимо в конце дописать список с аргументами в круглых скобках. Как в первом примере: getf(1)(x), первые скобки - аргумент для функции getf, вторые скобки - аргумент для вызова функции, указатель на которую вернет getf.

Добавлено через 2 минуты
Цитата Сообщение от Azazel-San Посмотреть сообщение
или так
А вот тут уже не понял, чем это лучше std::function. Начинает казаться, что многие нововведения становятся всё менее и менее логичными.
1
0 / 0 / 1
Регистрация: 29.06.2016
Сообщений: 110
25.02.2019, 23:10  [ТС]
valen10, Azazel-San, Avaddon74, большое всем спасибо, выручили!
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
25.02.2019, 23:38
Цитата Сообщение от valen10 Посмотреть сообщение
чем это лучше std::function
Ничем, в данном случае это просто обертка из <type_traits>, которая позволяет получить указатель на указанный тип Т (или на тип Т на который указывает ссылка), правда не уверен что я верно объяснил.

Добавлено через 5 минут
valen10, отсюда можно и так написать
C++
1
2
void func();
using FunctionPtr = decltype(func);
Добавлено через 14 минут
Avaddon74, ваш вариант может быть таким
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <iomanip>
#include <type_traits>
 
using func_p = std::add_pointer<void()>::type;
 
void const* foo(func_p const& lambda) {     
    return &lambda; 
}
 
int main() {
    void const* p = foo([]{ std::printf("foo()\n"); });
    auto f = static_cast<func_p const*>(p);
    (*f)();
}
А не reinterpret_cast, который на самом деле ничего не кастит, а только делает вид.
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.02.2019, 00:16
Цитата Сообщение от valen10 Посмотреть сообщение
многие нововведения становятся всё менее и менее логичными
Не совсем уверен, что микроскоп виноват в том, что им забивают гвозди

Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
2
3
4
5
int main() {
    void const* p = foo([]{ std::printf("foo()\n"); });
    auto f = static_cast<func_p const*>(p);
    (*f)();
}
Здесь UB: (*f)();. Указатель - параметр функции умрет в конце выражения (2), а в этом коде у него берется адрес и возвращается. Не надо так делать
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
26.02.2019, 00:27

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Не надо так делать
Далее примера это не должно было пойти



Добавлено через 27 секунд

Не по теме:

DrOffset, кста, у меня есть еще одна ошибка)



Добавлено через 6 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
Здесь UB: (*f)();. Указатель - параметр функции умрет в конце выражения (2), а в этом коде у него берется адрес и возвращается.
Хотя тогда мой код не должен был бы сработать? Я что-то такое подозревал) Введете поправки?

Добавлено через 1 минуту
DrOffset, типо так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iomanip>
#include <type_traits>
 
using func_p = std::add_pointer<void()>::type;
 
void const* foo(func_p const& lambda) {     
    return &lambda; 
}
 
void bar() { std::printf("foo()\n"); }
 
int main() {
    void const* p = foo(bar);
    auto f = static_cast<func_p const*>(p);
    (*f)();
}
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.02.2019, 00:36
Цитата Сообщение от Azazel-San Посмотреть сообщение
типо так?
Ничего не изменилось. Все так же UB.
И программа, собранная GCC, кстати, на этом коде честно падает.

Добавлено через 7 минут
Цитата Сообщение от Azazel-San Посмотреть сообщение
Введете поправки?
Ну хотя бы так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iomanip>
#include <type_traits>
 
using func_p = std::add_pointer<void()>::type;
 
void const* foo(func_p const& lambda) {     
    return &lambda; 
}
 
int main() {
    
    func_p fp = []{ std::printf("foo()\n"); };
    void const* p = foo(fp);
    auto f = static_cast<func_p const*>(p);
    (*f)();
}
Только нет особого смысла в этих приседаниях с двойным указателем. Только потому, что боязно использовать reinterpret_cast?

____
Кстати, реализация не обязана гарантировать, что указатель на функцию поместится в void *, а до С++11 это и вовсе было UB. (это замечание к коду поста №2)
2
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
26.02.2019, 00:42
Цитата Сообщение от DrOffset Посмотреть сообщение
Только нет особого смысла в этих приседаниях с двойным указателем.
Мне понравилось, узнал новое. Конечно смысла нету, нормальный вариант представили в посте 6.
Цитата Сообщение от DrOffset Посмотреть сообщение
Только потому, что боязно использовать reinterpret_cast?
Не, не боязно, просто с ним каждый могет) Тут такая ситуация что если уже мы пошли на void*, то чего reinterpret_cast'a боятся?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.02.2019, 00:46
Цитата Сообщение от Azazel-San Посмотреть сообщение
Мне понравилось, узнал новое.
Я думаю вы и так знали, что возврат указателей на локальные или временные объекты и последующий доступ к уже мертвым объектам через них - это UB
Просто за искусственной вычурностью вашего примера это не сразу видно.
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
26.02.2019, 00:52
Цитата Сообщение от DrOffset Посмотреть сообщение
Я думаю вы и так знали, что возврат указателей на локальные или временные объекты и последующий доступ к уже мертвым объектам через них - это UB
Знал и знаю, но почему то мне эти знания не помогли..
Цитата Сообщение от DrOffset Посмотреть сообщение
Просто за искусственной вычурностью вашего примера это не сразу видно.
Да, видно там все.. Ну и пример хотел под задание ТС подстроить..

Узнал новое, это типо поигрался с указателями, кстати если писать ООП обертку над чистым Си, там где-то такие приседания через void* и происходят?

Добавлено через 2 минуты
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
2
void func();
using FunctionPtr = decltype(&func);
Еще себя поправлю
0
 Аватар для Avaddon74
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
26.02.2019, 00:55
Цитата Сообщение от DrOffset Посмотреть сообщение
Кстати, реализация не обязана гарантировать, что указатель на функцию поместится в void *, а до С++11 это и вовсе было UB.
Спасибо, учту. Пользуясь случаем, спрошу, а какой размер void? по битности ОС?

Добавлено через 1 минуту
Цитата Сообщение от Avaddon74 Посмотреть сообщение
по битности ОС?
Ну собственно проверил уже если приложение компилируется в x32 то размер 4, а если в x64 то размер 8
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.02.2019, 00:55
Помогаю со студенческими работами здесь

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

Функция, возвращающая умный указатель
Здравствуйте, помогите пожалуйста создать функцию, возвращающую умный указатель. Мой вариант не рабочий: class InterfaceVideo{ public:...

Функция, возвращающая указатель на структуру
Помогите пожалуйста понять в чем ошибка! Функция create должна возвращать указатель на структуру Vector #include &lt;iostream&gt; ...

Функция возвращающая указатель на int
Не могу понять ошибки. // prata 7 pt to function.cpp : Defines the entry point for the console application. // #include...

Функция, возвращающая указатель на структуру
Ребят помогите пожалуйста,как создать функцию возвращающую указатель на структуру,в общем задание звучит так:написать библиотеку для...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru