Неупорядоченная карта: проблема с использованием указателя на функцию-член класса - PullRequest
0 голосов
/ 12 декабря 2018

У меня следующая проблема: я пишу простой эмулятор chip8 и имею огромный класс функций интерпретатора, к которым я хотел бы получить доступ через коды операций в качестве ключей, например со словарем.Это должно заменить массивный случай переключения, и я понимаю, что для этой цели неупорядоченная карта является хорошим инструментом для использования.

Этот подход легко работает только с функциями (из-за их статической области действия, я полагаю), но не с классами, из-за той же концепции области действия.Я немного новичок в указателях и самом C ++, и не уверен, как решить проблему (попробовав много вещей, например, сделав статические функции-члены, указав на экземпляр класса функции и тому подобное - они не скомпилируются).Доступ к iter-> second вообще ничего не возвращает, хотя map.count говорит, что член существует.

#include <cstdio>
#include <unordered_map>

class test{
public:
    test();
    void fptr(void);
};

void test::fptr(void){
    printf("fptr\n");
}

typedef void (test::*Interpreter)(void);
typedef std::unordered_map<int, Interpreter> fmap;

int main(void){
    fmap map;
    int input = 0;

    map.emplace(1, &test::fptr);

    printf("input int to access:\n");
    scanf("%i", &input);

    auto iter = map.find(input);
    if(iter == map.end() ){
        printf("No such function\n");
    }
    else{
        iter->second; //iter->second() will not compile, accessing like this returns nothing
    }

//checks that the emplaced function actually exists
    for (auto& x: {1}) {
    if (map.count(x)>0){ 
        printf("map has %i\n", x);
    }
    else {
        printf("map has no %i\n", x);
    }

    return 0
}

1 Ответ

0 голосов
/ 12 декабря 2018

Используйте std::invoke из заголовка functional для его выполнения (C ++ 17):

test t;
std::invoke(iter->second, t);

В конце концов, вам нужно вызвать его для объекта.Сам метод не может быть выполнен.

Если у вас нет C ++ 17 (IIRC):

test t;
(t.*(iter->second))();
...