Определите объект и метод в функторе, используя boost :: function и boost :: bind - PullRequest
2 голосов
/ 23 марта 2009

Я хотел бы получить указатель на объект и указание, какой метод вызовет функтор из функтора, созданного с использованием boost :: function и boost :: bind. Это позволит мне автоматически определить порядок, в котором должна быть выполнена группа функторов.

Следующий (псевдо) код (см. POINTER_OF & METHOD_OF ) показывает, что я пытаюсь сделать:

class myClassA
{
  public:
    DoIt(int i) { return i+i; }
};

class myClassB
{
  public:
    DoItToo(double d) { return d*d; }
};

typedef boost::function0<int> Functor;

myClassA classA;
myClassB classB;

Functor funcA = boost::bind( &myClassA::DoIt, &classA, 10 );
Functor funcB = boost::bind( &myClassB::DoItToo, &classB, 12.34 );

// Create a vector containing some functors and try to determine the objects
// they are called upon and the methods they invoke
std::vector<Functor> vec;
vec.push_back( funcA );
vec.push_back( funcB );

for (int i = 0; i < vec.size();i++)
{
  if (POINTER_OF(vec[i]) == &classA)
  {
    // This functor acts on classA
    if (METHOD_OF(vec[i]) == &myClassA::DoIt)
    {
      // This functor calls the 'DoIt' method.
    }
    else if (METHOD_OF(vec[i]) == &myClassB::DoItToo)
    {
      // This functor calls the 'DoItToo' method.
    }
  }
  // etc...
}

Заранее спасибо!

Ответы [ 3 ]

4 голосов
/ 23 марта 2009

Я знаю, что следующее не является строгим ответом на ваш вопрос, но.

Не делай этого. Используйте вместо этого полиморфизм. Это одна из самых странных вещей, которые я видел в своем текущем коде проекта: если указатель на функцию указывает на «someFunction» - выполните некоторые дополнительные действия.

Вы можете добавить дополнительное поведение без особого изменения классов с помощью шаблона проектирования Decorator. Это расширит ваш myClassA :: DoIt с помощью Decorator :: DoIt.

http://en.wikipedia.org/wiki/Decorator_pattern

0 голосов
/ 24 марта 2009

boost::function объекты сопоставимы по равенству, поэтому вы должны иметь возможность делать что-то вроде

if (vec[i] == boost::bind( &myClassA::DoIt, &classA, 10 ))
{
   // ... this Functor calls DoIt on classA with argument 10
}

Я подозреваю, что вы ищете что-то более общее, хотя. Изучение деталей реализации boost/function_equal.hpp (то есть boost::bind function_equal_impl) может дать вам некоторое представление о том, как выборочно протестировать подмножество boost::bind аргументов.

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

0 голосов
/ 23 марта 2009

Нет, я не думаю, что вы можете получить цель функции повышения, которая установлена ​​для привязки повышения (т.е. METHOD_OF). Согласно этому сообщению в списке рассылки поддержки, это связано с тем, что тип возвращаемой привязки формально не указан.

Редактировать: Ссылка на более ранний вопрос, связанный с этим вопросом: demote-boostfunction-to-a-plain-function-pointer

...