Как да извикам функция указател към член?

Получавам грешка при компилиране (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 е указател към невалидна функция член на класа, посочен от *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