Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.58/19: Рейтинг темы: голосов - 19, средняя оценка - 4.58
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2

Передача функции-члена в качестве аргумента (не через указатель)

23.03.2013, 21:38. Показов 4116. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет!
Озадачился такой проблемой - вот пример того, что нужно
C++
1
2
3
4
typedef void(class1::*method)();
void func (method) {};
 
func (&class1::func); // вызов
Но хочется сделать кошерно, и, чтоб было совсем кошерно, решил заюзать С++11, которого я почти не знаю
Вот что получилось
C++
1
2
3
4
typedef std::function<void(param&)> method;
void func (method){};
 
func(std::bind(&class1::methodName, object_ptr, std::placeholders::_1)); // вызов
согласитесь - выглядет ужасно. Хочеться std::bind() спрятать внуть функции, т.е. вот так
C++
1
2
3
4
5
6
7
8
typedef void(class1::*method)();
 
void func (method)
{
    // blah blah blah std::bind (method, ...)
}
 
func(&class1::methodName); // вызов
но не могу придумать как обойтись без указателя void(class1::*method)().
Знаю, что есть люди, которы ориентируются в С++11, может есть идеи?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.03.2013, 21:38
Ответы с готовыми решениями:

Вызов родовой функции (нужно передать массив в качестве аргумента функции через указатель)
#include &lt;iostream&gt; using namespace std; template &lt;class T1&gt; class mas { public: T1 n; T1 a; void input() ...

Передать указатель на массив в качестве аргумента функции
Работаю в Visual Studio 2012 Ultimate, задание - сделать свою библиотеку. Пишу на Visual C++. Решил делать просто - 3 библиотечных функции,...

Как передать функции указатель на функцию в качестве аргумента?
как передать функции указатель на функцию в качестве аргумента?

8
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
23.03.2013, 23:40
Но ведь если функция не static, объект все равно нужно передавать как-то. Над каким объектом будет выполняться func?
C++
1
func(&class1::methodName);
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
24.03.2013, 08:35
Задача состоит в том, чтобы каким-то образом специализировать передаваемые методы, т.е. ограничить классы, чьи методы могут передаваться, ограничить количество аргументов передаваемой функции?
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
24.03.2013, 10:26  [ТС]
Похоже я криво задачу описал)
Задача состоит в том, чтобы избавиться от указателя. Грубо говоря, что писать в typedef
C++
1
typedef void(class1::*method)();
?
Т.е. что-нибудь типа
C++
1
typedef std::function<void(param&)> method;
только для функции-члена.
Цитата Сообщение от Tulosba Посмотреть сообщение
Но ведь если функция не static, объект все равно нужно передавать как-то. Над каким объектом будет выполняться func?
Над этим я уже подумал, все нормально.
0
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
24.03.2013, 12:08
Фрагмент примера из cppreference:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <functional>
#include <iostream>
 
struct Foo {
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_+i << '\n'; }
    int num_;
};
 
int main()
{
    // store a call to a member function
    std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
    Foo foo(314159);
    f_add_display(foo, 1);
}
1
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
24.03.2013, 12:21
Kastaneda, т.е. никаких ограничений не ставится? Тогда почему бы просто не сделать функцию шаблонной?
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
#include <iostream>
#include <functional>
 
template <class F, class O, class... Args>
auto call(F&& function, O& object, Args&&... args)
    -> decltype(function(&object, std::forward<Args>(args)...))
{
    return function(&object, std::forward<Args>(args)...);
}
 
class Foo
{
public:
    Foo()
    {
 
    }
 
    int add(int a, int b) const
    {
        return a + b;
    }
};
 
int main()
{
    const Foo f;
    std::cout << call(std::mem_fn(&Foo::add), f, 4, 6) << std::endl;
    return 0;
}
1
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
24.03.2013, 14:35  [ТС]
Nick Alte, спасибо, то что нужно. Причем я вчера читал именно ту самую страницу из твоей ссылки, как-то мимо глаз пропустил данную возможность. Я почему-то решил, что std::function<> не может быть функцией-членом.

soon, круто, но вариант с std::function<> куда проще
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
24.03.2013, 14:46
Kastaneda, просто я до сих пор не понял, что вам требуется Я считал, что вам нужна функция, принимающая метод. Разумеется, по аналогии с Nick Alte можно упростить мой вариант.
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
#include <iostream>
#include <functional>
 
class Foo
{
public:
    Foo()
    {
 
    }
 
    int add(int a, int b) const
    {
        return a + b;
    }
};
 
int main()
{
    Foo f;
    auto add = std::mem_fn(&Foo::add);
    std::cout << add(&f, 4, 6) << std::endl;
    return 0;
}
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
24.03.2013, 16:31  [ТС]
C++
1
add(&f, 4, 6)
я до сегодняшнего дня с данной семантикой не был знаком, ну теперь буду знать
Я считал, что вам нужна функция, принимающая метод.
Ну да, вот примерно что я делаю
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
class Menu
{
public:
    enum Item {Show};
 
    Item getMenuItem();
};
 
class Executer
{
public:
    void show(container&);
private:
};
 
class Worker
{
public:
    void addItem (Menu::Item item, container::method method)
    {
        methods[item] = method;
    }
 
    void work ()
    {
        mehtods[Menu::getMenuItem()](*cont);
    }
 
private:
    std::map<Menu::Item, container::method> methods;
    container *cont;
};
 
worker.addItem(Show, &container::show);
писал на коленке для примера.

Собственно проблема была в том, как сделать typedef container::method.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.03.2013, 16:31
Помогаю со студенческими работами здесь

Передача функции в качестве аргумента
Передаю в функцию (А) в качестве аргумента другую функцию (Б). В функцию Б передаю переменную из А, но массив аргументов оказывается пуст....

Считывание одной строки, не используя в качестве аргумента функции двойной указатель
Язык C начал изучать недавно. Хочу написать функцию считывания строки без ограничения на её длину. Т.е. вообще без ограничения, не считая...

Передача массива в качестве аргумента функции
В общем нужно передать массив в качестве аргумента без указания его размера, чтобы в дальнейшем присвоить все его содержимое другому...

Передача функции в качестве аргумента массив
Помогите пожалуйста! есть некая рекурсивная функция N которая принимает 2 целочисленные переменные и массив; void N(int, int,...

как передать функции в качестве аргумента указатель на функцию описанной в другом классе?
Есть два класса A и B в классе A есть две функции funcA_1 и funcA_2 в классе B - funcB в funcA_1 создается экземпляр класса B и...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера 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. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru