Как мне вызвать указатель на член-функцию? - PullRequest
10 голосов
/ 18 декабря 2009

Я получаю ошибку компиляции (MS VS 2008), которую просто не понимаю. После того, как я возился с ним в течение многих часов, все становится размытым, и я чувствую, что есть кое-что очень очевидное (и очень глупое), что я скучаю. Вот необходимый код:

typedef int (C::*PFN)(int);

struct MAP_ENTRY
    {
    int id;
    PFN pfn;
    };

class C
    {
    ...
    int Dispatch(int, int);
    MAP_ENTRY *pMap;
    ...
    };

int C::Dispatch(int id, int val)
    {
    for (MAP_ENTRY *p = pMap; p->id != 0; ++p)
        {
        if (p->id == id)
            return p->pfn(val);  // <--- error here
        }
    return 0;
    }

Компилятор утверждает на стрелке, что «термин не оценивает функцию, принимающую 1 аргумент». Почему бы и нет? PFN является прототипом функции с одним аргументом, а MAP_ENTRY.pfn является PFN. Что мне здесь не хватает?

Ответы [ 4 ]

17 голосов
/ 18 декабря 2009

p->pfn - указатель типа указатель на функцию-член. Чтобы вызвать функцию через такой указатель, вам нужно использовать оператор ->* или оператор .* и указать объект типа C в качестве левого операнда. Вы не сделали.

Я не знаю, какой объект типа C предполагается использовать здесь - только вы это знаете - но в вашем примере это может быть *this В этом случае вызов может выглядеть следующим образом

(this->*p->pfn)(val)

Чтобы он выглядел немного менее запутанным, вы можете ввести промежуточную переменную

PFN pfn = p->pfn;
(this->*pfn)(val);
8 голосов
/ 18 декабря 2009

Попробуйте

return (this->*p->pfn)(val);
1 голос
/ 01 сентября 2010

Просто чтобы поделиться своим собственным опытом, я обнаружил ошибку в g ++, вызванную этим утверждением:

  (this -> *stateHandler)() ;

Где stateHandler - указатель на функцию-член void класса, на который ссылается * this. Проблема была вызвана пробелами между стрелками оператора. Следующий фрагмент отлично компилируется:

(this->*stateHandler)() ;

Я использую g ++ (GCC) 4.4.2 20090825 (предварительный выпуск). FWIW.

0 голосов
/ 18 декабря 2009

p-> pfn - указатель на функцию. Вы должны использовать *, чтобы заставить это работать. Изменить на

(*(p->pfn))(val)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...