Как вызвать функцию указателя на член?

Я получаю ошибку компиляции (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. Что мне здесь не хватает?


person chrisd    schedule 18.12.2009    source источник
comment
Синтаксис C ржавый, поэтому не добавлять в качестве ответа, если это не return (* (p- ›pfn)) (val) ;? -   -  person Binary Worrier    schedule 18.12.2009
comment
Нет, это дает ошибку * недопустимо для операндов типа C :: PFN.   -  person chrisd    schedule 18.12.2009
comment
возможный дубликат Вызов методов класса C ++ через указатель функции   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 01.07.2015


Ответы (4)


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

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

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

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

PFN pfn = p->pfn;
(this->*pfn)(val);
person AnT    schedule 18.12.2009

Пытаться

return (this->*p->pfn)(val);
person Michael Krelin - hacker    schedule 18.12.2009
comment
ДА!! Вот и все. Большое спасибо. Вы, ребята, невероятные. Я занимался этим часами и получил ответ менее чем за 10 минут. - person chrisd; 18.12.2009

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

  (this -> *stateHandler)() ;

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

(this->*stateHandler)() ;

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

person Gearoid Murphy    schedule 01.09.2010

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

(*(p->pfn))(val)
person cuteCAT    schedule 18.12.2009