Член класса функции карты внутри самого класса - PullRequest
0 голосов
/ 25 февраля 2020

Мне сложно отобразить функции члена класса внутри самого класса

#include <functional>
#include <map>
#include <string>

class Foo{
    public:
    void bar() {}
    void jar() {}

    private:
    std::map<std::string, std::function<void(void)>> myMap =
    {
        {"bar", bar},
        {"jar", jar}
    };
};

Компилятор говорит нет

Код серьезности Описание Файл проекта Состояние подавления строки Состояние подавления (активно) ) E0289 нет экземпляра конструктора "std :: map <_Kty, _Ty, _Pr, _Allo c> :: map [с _Kty = std :: string, _Ty = std :: function, _Pr = std :: less, _Alloc = std :: allocator >>] "соответствует списку аргументов Stackoverflow C: \ Stackoverflow \ Foo.h 13

Пожалуйста, помогите, спасибо.

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

Некоторые альтернативы ответу @ rafix07:

Использование лямбд с захватом this:

std::map<std::string, std::function<void(void)> > myMap2 =
{
    {"bar", [this]{ bar(); }},
    {"jar", [this]{ jar(); }}
};

или указатели на функции-члены в std::function:

std::map<std::string, std::function<void(Foo*)> > myMap2 =
{
    {"bar", &Foo::bar},
    {"jar", &Foo::jar}
};

Обратите внимание, что запись &Foo:: необходима для получения указателя на функцию-член c, не относящуюся к состоянию. Ни &bar, ни bar не допускаются такими, какими они являются для свободных функций.

1 голос
/ 25 февраля 2020

bar и jar являются функциями-членами. Они принимают указатель - this в качестве первого скрытого параметра, вы не можете рассматривать их как свободные функции. И вы не можете просто заключить их в function<void(void)>, указав на них указатели - что вы делаете сейчас.

Вы должны использовать std::bind, чтобы связать this с функциями-членами (или использовать лямбда-выражения):

std::map<std::string, std::function<void(void)> > myMap2 =
{
    {"bar", std::bind(&Foo::bar,this)},
    {"jar", std::bind(&Foo::jar,this)}
};

или сохранить указатели на функции:

std::map<std::string, void (Foo::*)(void) > myMap =
{
    {"bar", &Foo::bar},
    {"jar", &Foo::jar}
};
...