Как вызвать функцию-указатель-член?
Я получаю ошибку компиляции (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. Что мне здесь не хватает?
Ответы
Ответ 1
p->pfn
- это указатель типа указателя на член. Чтобы вызвать функцию через такой указатель, вам нужно использовать оператор ->*
или operator .*
и поставить объект типа C
в качестве левого операнда. Вы этого не сделали.
Я не знаю, какой объект типа C
предполагается использовать здесь - только вы это знаете, но в вашем примере это может быть *this
. В этом случае вызов может выглядеть следующим образом
(this->*p->pfn)(val)
Чтобы сделать его немного менее запутанным, вы можете ввести промежуточную переменную
PFN pfn = p->pfn;
(this->*pfn)(val);
Ответ 2
Try
return (this->*p->pfn)(val);
Ответ 3
Просто, чтобы прослушивать свой собственный опыт, я столкнулся с ошибкой в g++, вызванной этим утверждением:
(this -> *stateHandler)() ;
Где stateHandler является указателем на функцию элемента void класса, на который ссылается * this. Проблема была вызвана пробелами между оператором стрелки. Следующий фрагмент компиляции отлично:
(this->*stateHandler)() ;
Я использую g++ (GCC) 4.4.2 20090825 (preerelease). FWIW.
Ответ 4
Сделайте себе одолжение и используйте boost:: function (и boost:: bind too!)
Ответ 5
это не отвечает на ваш вопрос, но подумайте об использовании boost:: function и boost:: bind. Он вводит довольно большую зависимость в вашу кодовую базу, но это стоит того, чтобы делать крупные проекты.
Ответ 6
p- > pfn - указатель на функцию. Вы должны использовать *, чтобы сделать его функцией. Изменить на
(*(p->pfn))(val)