Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Передача указателя на функцию-член


Автор: Inversus 28.8.2016, 23:47
Всем привет !

Необходимо передать функцию-член в качестве параметра другой функции-члену. Следующий код

Код

class Menu {
    public:
    void spin();   
};

void Menu::spin() {
  ;
}

class Encoder {
  public:
    void setSpinFunc(void(Menu::*i)());
};

void Encoder::setSpinFunc(void(Menu::*i)()) {
  ;
}

int main()
{
    Menu m();
    Encoder e();
    e.setSpinFunc(m.spin);
}


вызывает ошибку: request for member 'setSpinFunc' in 'e', which is of non-class type 'Encoder()'

Уже долго туплю над этим, похоже сам не въеду, разъясните что не так.

Автор: baldman88 29.8.2016, 08:15
Все просто. Не нужно ставить скобки после m и e в main. Ну и вот это:
Код
void setSpinFunc(void(Menu::*i)());
ерунда какая-то. Так у Вас тоже ничего не выйдет.

Автор: xvr 29.8.2016, 12:22
Код

    Menu m;
    Encoder e;
    e.setSpinFunc(&Menu::spin);


Автор: azesmcar 29.8.2016, 15:39
а лучше так
Код

#include <iostream>
#include <functional>

class Menu {
    public:
    void spin();   
};

void Menu::spin() {
    std::cout << "callback" << std::endl;
}

class Encoder {
public:
    void setSpinFunc(std::function<void()> callback);
};

void Encoder::setSpinFunc(std::function<void()> callback) {
    callback();
}

int main()
{
    Menu m;
    Encoder e;
    e.setSpinFunc(std::bind(&Menu::spin, &m));
}

Автор: azesmcar 29.8.2016, 16:07
Цитата(Inversus @  28.8.2016,  23:47 Найти цитируемый пост)
    Menu m();
    Encoder e();

в C++ все, что может быть рассмотрено как объявление функции является объявлением функции. Тяжелое наследие Си.
Вызов конструктора будет в данном случае рассмотрен как объявление прототипа функции, потому скобки ставить не надо.

Автор: Inversus 29.8.2016, 22:25
Цитата(azesmcar @  29.8.2016,  16:07 Найти цитируемый пост)
в C++ все, что может быть рассмотрено как объявление функции является объявлением функции. Тяжелое наследие Си.
 А, понятно.

Цитата(azesmcar @  29.8.2016,  15:39 Найти цитируемый пост)
std::function<void()> callback
 - некогда не пользовался такой конструкцией, это получается универсальный указатель ? 
Цитата(azesmcar @  29.8.2016,  15:39 Найти цитируемый пост)
std::bind(&Menu::spin, &m)
 - тоже интересно, придется вникать )

xvr, azesmcar,  Спасибо. Жаль, не могу плюсики поставить  smile 

P.S. На другом форуме тот же вопрос задавал - начался срач не с чего smile Что для счастья программиста надо  smile
Ууу, там уже базар про то как наши космические корабли бороздят просторы большого театра  smile 

Автор: azesmcar 29.8.2016, 23:32
Цитата(Inversus @  29.8.2016,  22:25 Найти цитируемый пост)
 - некогда не пользовался такой конструкцией, это получается универсальный указатель ? 

современный указатель на функцию. прелести нового стандарта. и std::bind тоже (современная замена std::mem_fun, std::bind1st, std::bind2nd и ему подобных).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)