Указатели на функции - PullRequest
       29

Указатели на функции

2 голосов
/ 31 августа 2010

Я должен передать функцию в указатель. Для этого я использую boost :: function. Функция, которая ловит указатель, перегружена для разных подписей. Например:

void Foo(boost::function<int ()>) { ... }
void Foo(boost::function<float ()>) { ... }
void Foo(boost::function<double ()>) { ... }

Теперь я хочу передать туда указатель на метод класса:

class test
{
   public:
      float toCall() { };
};

class Wrapper
{
  Wrapper() {
    test obj;
    Foo(boost::bind(&test::toCall, this));
  }
};


error: no matching function for call to ‘Foo(boost::_bi::bind_t<float, boost::_mfi::mf0<float, test>, boost::_bi::list1<boost::_bi::value<Wrapper*> > >)’
    note: candidates are: Foo(boost::function<float()>&)

Ответы [ 3 ]

6 голосов
/ 31 августа 2010

Nonono это не может работать.Потому что boost::function<...> имеет шаблонный конструктор для принятия любых типов.Совместимость с подписью звонка проверяется позже.Разрешение перегрузки не может решить эту проблему.

Кроме того, я думаю, что вы хотите передать &obj вместо this.Попробуйте преобразовать явно:

Foo(boost::function<float ()>(boost::bind(&test::toCall, &obj)));

Это очень уродливо, хотя, возможно, вы захотите ввести typedef

void Foo(FloatHandler) { ... }
...
FloatHandler f(boost::bind(&test::toCall, &obj));
Foo(f);

Или в конечном итоге вы можете сделать Foo шаблоном, который принимает только любые вызываемыевведите T.Я подозреваю, что это может быть самым простым, потому что в общем случае я подозреваю, что вы не знаете, к чему boost::function<...> вам нужно обратиться.А как насчет людей, которые хотят вернуть std::complex<>.Итак ...

template<typename T>
void Foo(T) { ... }
...
Foo(boost::bind(&test::toCall, &obj));

Надеюсь, это поможет.

2 голосов
/ 31 августа 2010

В строке

Foo(boost::bind(&test::toCall, this));

this имеет тип Wrapper.Но привязка не может найти метод toCall.

Вот исправленная версия (полная, компилируется на g ++ 4.3.2), что, вероятно, вы пытаетесь сделать:

#include <boost/bind.hpp>
#include <boost/function.hpp>

void Foo(boost::function<int()>) {}
void Foo(boost::function<float()>) {}
void Foo(boost::function<double()>) {}

struct test {
  float toCall() {return 0.0f;}
};

int main(int,char**) {
  test obj;
  boost::function<float()> tgt=boost::bind(&test::toCall,obj);
  Foo(tgt);
  return 0;
}

Как отмечается в ответе AndreyT, тип возвращаемого значения bind ... немного странный, отсюда явное приведение к соответствующему типу функции.

1 голос
/ 31 августа 2010

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

В то время как boost::function может быть построен из результата преобразования boost::bind,Разрешение перегрузки в этом случае является «слишком сложным» для C ++.(Удален мой плохой пример, который на самом деле не иллюстрирует правильную проблему).

...