Вызов функции, указанной указателем на член-функцию из структуры - PullRequest
4 голосов
/ 27 июля 2011

У меня есть класс Test со своеобразной структурой данных. Членом класса Test является std::map, где ключом является std::string, а отображаемым значением является struct, определяемое следующим образом:

typedef struct {
  void (Test::*f) (void) const;
} pmf_t;

Инициализация карты в порядке. Проблема в том, когда я пытаюсь вызвать указанную функцию. Я сделал игрушечный пример, воспроизводящий проблему. Вот оно:

#include <iostream>
#include <map>

using namespace std;

class Test;
typedef void (Test::*F) (void) const;
typedef struct {
  F f;
} pmf_t;


class Test
{
public:
  Test () {
    pmf_t pmf = {
      &Test::Func
    };
    m["key"] = pmf;
  }
  void Func (void) const {
    cout << "test" << endl;
  }
  void CallFunc (void) {
    std::map<std::string, pmf_t>::iterator it = m.begin ();
    ((*it).second.*f) (); // offending line
  }

  std::map<std::string, pmf_t> m;
};


int main ()
{

  Test t;
  t.CallFunc ();

  return 0;
}

Спасибо заранее, Jir

Ответы [ 5 ]

5 голосов
/ 27 июля 2011

Имя типа pmf_t - f, поэтому первое изменение - удалить *, чтобы получить second.f.Это дает вам значение указателя на член.Чтобы использовать указатель на член, вам нужен экземпляр.Единственный доступный вам тип правильного типа - this, поэтому используйте его с оператором ->*:

(this->*it->second.f)();

Вам нужны круглые скобки вокруг всего, иначе компилятор считает, что выпытается вызвать it->second.f() (что не разрешено), а затем применить результат к ->*.

3 голосов
/ 27 июля 2011

Неправильная строка пытается вызвать функцию-член без какого-либо объекта для ее вызова. Если намерение состоит в том, чтобы вызвать его для объекта this, я считаю, что вызов должен выглядеть как

( this->* ((*it).second.f) )(); 

Где this->* - синтаксис разыменования указателя на член для текущего объекта. ((*it).second.f) - указатель, извлеченный из карты, а () - оператор вызова для фактического вызова функции.

Возможно, это хорошее упражнение, но в остальном ограниченное использование.

1 голос
/ 27 июля 2011

Возможно, уже слишком поздно для этого вопроса, но, казалось бы, сложный синтаксис может быть разбит на две простые строки, поэтому он выглядит довольно ясно:

1 голос
/ 27 июля 2011

попробуйте это:

(this->*((*it).second.f)) ();
1 голос
/ 27 июля 2011

Я думаю, вы можете проверить C ++ FAQ на этом. Синтаксис, по-видимому, довольно сложен для понимания (на самом деле они рекомендуют использовать макрос).

...