Как вызвать указатель на функцию-член, когда он является членом данных класса?

struct B
{
  void (B::*pf)(int, int);  // data member
  B () : pf(&B::foo) {}
  void foo (int i, int j) { cout<<"foo(int, int)\n"; } // target method
};

int main ()
{
  B obj;
  // how to call foo() using obj.pf ?
}

В приведенном выше тестовом коде pf является элементом данных B. Каково правило грамматики для его вызова? Это должно быть прямолинейно, но я не получаю правильного совпадения. например Если я попробую obj.*pf(0,0);, то получу:

error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘pf (...)’, e.g. ‘(... ->* pf) (...)’

person iammilind    schedule 11.06.2011    source источник
comment
см.: ideone.com/p3a5G   -  person Geoffroy    schedule 11.06.2011
comment
возможный дубликат вызова методов класса C++ через указатель функции   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 01.07.2015
comment
@CiroSantilli六四事件法轮功纳米比亚威视, нет, оба разные. Ваш связанный вопрос объясняет, "How to call class member using function pointer?", пока я спрашиваю "<...same...>, when the function pointer itself is a class member also.". Обратите внимание, что ответы на оба вопроса разные.   -  person iammilind    schedule 01.07.2015
comment
Я согласен, что у этого есть один дополнительный шаг. но я чувствовал, что это можно легко вывести, если вы знаете синтаксис указателя функции: (obj.*ptr), только здесь ptr == (obj.ptr). Но раз уж вы не согласны, я воздержусь ;-)   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 01.07.2015


Ответы (3)


Нравится:

(obj.*obj.pf)(0, 1);

Доступ к члену (.) имеет более высокий приоритет, чем указатель на оператор члена, поэтому это эквивалентно:

(obj.*(obj.pf))(0, 1);

Поскольку вызов функции также имеет более высокий приоритет, чем указатель на оператор-член, вы не можете сделать:

obj.*obj.pf(0, 1) /* or */ obj.*(obj.pf)(0, 1)

Поскольку это было бы эквивалентно:

obj.*(obj.pf(0, 1)) // grammar expects obj.pf to be a callable returning a
                    // pointer to member
person CB Bailey    schedule 11.06.2011
comment
+1, спасибо; это уникально; что бы произошло, если бы obj был членом B ? :) - person iammilind; 11.06.2011
comment
@iammilind: obj имеет тип B, поэтому он не может быть членом B, поскольку это подразумевает рекурсивное определение класса. Можете ли вы уточнить, что вы имеете в виду? - person CB Bailey; 11.06.2011
comment
Нет, даже если внутри B был такой член, как obj; это не будет проблемой, пока у вас нет (....) подписи. Я ясно с этой проблемой сейчас. Таким образом, либо это будет ошибка компиляции, либо он будет работать нормально. - person iammilind; 11.06.2011

pf — это указатель на метод, и вы хотите вызвать метод, на который он указывает, поэтому вам нужно использовать

(obj.*obj.pf)(1, 2);

В нем говорится, что объект obj вы вызываете метод, указанный pf

Смотрите результат здесь:

http://ideone.com/p3a5G

person Geoffroy    schedule 11.06.2011

Синтаксис весьма неестественен, но является следствием правил приоритета С++...

(obj.*obj.pf)(1, 2);
person 6502    schedule 11.06.2011