boost :: bind к функции-члену класса

0

Я пытаюсь передать функцию члена, завернутую в автономную функцию через boost::bind. Ниже приведен сниженный образец.

// Foo.h
typedef const std::pair<double, double> (*DoubleGetter)(const std::string &);

class Foo : private boost::noncopyable {
public:
  explicit Foo(const std::string &s, DoubleGetter dg);
};

// Bar.h
struct Bar {
  const std::pair<double, double> getDoubles(const std::string &s);
};

// main.cpp
boost::shared_ptr<Bar> bar(new Bar());

std::string s = "test";
Foo foo(s, boost::bind(&Bar::getDoubles, *(bar.get()), _1));

Однако я получил ошибку компилятора с текстом:

/home/Loom/src/main.cpp:130: error: no matching function for call to 
‘Foo::Foo
( std::basic_string<char, std::char_traits<char>, std::allocator<char> >
, boost::_bi::bind_t
  < const std::pair<double, double>
  , boost::_mfi::mf1
    < const std::pair<double, double>
    , Bar
    , const std::string&
    >
  , boost::_bi::list2
    < boost::_bi::value<Bar>
    , boost::arg<1>
    >
  >
)

/home/Loom/src/Foo.h:32: note: candidates are: 
Foo::Foo(const std::string&, const std::pair<double, double> (*)(const std::string&))

/home/Loom/src/Foo.h:26: note:
Foo::Foo(const Foo&)

Какая проблема с кодом и как избежать таких проблем?

Теги:
member-functions
boost
compiler-errors
boost-bind

1 ответ

2
Лучший ответ

Указатели функции-члена не включают контекст (в отличие от функции лямбда или boost::function. Чтобы сделать работу кода, вам нужно заменить определение типа DoubleGetter образом:

typedef boost::function<const std::pair<double, double>(const std::string&)> DoubleGetter;

Также нет необходимости разыгрывать смарт-указатель при поставке контекста (Bar) (если вы намереваетесь сделать это, вы можете напрямую использовать оператор сокращенного разыменования):

// Pass the pointer directly to increment the reference count (thanks Aleksander)
Foo foo(s, boost::bind(&Bar::getDoubles, bar, _1));

Я также заметил, что вы определяете обычный указатель на функцию. Если вы хотите полностью исключить использование функции boost :: function, вы можете использовать следующий подход (я исключил неизменяемые части):

typedef const std::pair<double, double> (Bar::*DoubleGetter)(const std::string &);

class Foo : private boost::noncopyable {
public:
  explicit Foo(const std::string &s, Bar& bar, DoubleGetter dg);
  // Call dg by using: (bar.*dg)(s);
};

// Instantiate Foo with:
Foo foo(s, *bar, &Bar::getDoubles);
  • 2
    Почему вы разыменовываете SP? просто передайте bar в качестве общего указателя на boost-bind, который увеличит sp "владельцев" - это гарантирует, что bar не будет удален. В этом случае это не проблема, но в некоторых других может быть.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню