Указатель на класс функции boost bind
class Foo
{
double f1( int x, std::string s1 );
double f2( int x, SomeClass s2 );
}
Я хочу иметь возможность связывать s1 Foo.f1 без экземпляра foo для создания в сущности
typedef double (Foo::* MyFooFunc)( int )
MyFooFunc func1 = boost::bind( &Foo::f1, _1, _2, "some string" );
MyFooFunc func2 = boost::bind( &Foo::f2, _1, _2, SomeClass );
Затем я передаю func1 и func2 в качестве параметров другим функциям, внутри которых Foo наконец-то связывается:
void SomeOtherFunction( MyFooFunc func )
{
Foo foo;
boost::function< double (int) > finalFunc =
boost::bind( func, foo, _1 );
}
Вопросы: возможно ли это? Если да, 1) как этого добиться? 2) Что такое декларация MyFooFunc?
2 ответа
typedef double (Foo::* MyFooFunc)( int );
MyFooFunc func1 = boost::bind( &Foo::f1, _1, _2, "some string" );
Результат boost::bind
не указатель на член, так func1
не может быть инициализирован как таковой во второй строке. Результат boost::bind
является неопределенным типом (который будет зависеть от параметров). Если вы используете C++0x, самый простой способ назвать результат вызова bind
это использовать auto
:
auto func1 = boost::bind( &Foo::f1, _1, _2, "some string" );
Другой простой способ (не ограниченный C++03) - просто не называть результат, а использовать его на месте:
SomeOtherFunction(boost::bind(&Foo::f1, _1, _2, "some string"));
Или вы можете использовать тип-стирание, чтобы сохранить результат boost::bind
в boost::function
с которым вы, кажется, знакомы. boost::function<double(Foo&, int)>
это возможность, но не единственный выбор.
Теперь нам нужно найти соответствующую подпись для SomeOtherFunction
: опять же, указатель на член не может быть инициализирован из результата вызова boost::bind
, так void SomeOtherFunction(MyFooFunc func);
не сработает Вместо этого вы можете сделать функцию шаблоном:
template<typename Func>
void SomeOtherFunction( Func func )
{
Foo foo;
boost::function< double (int) > finalFunc =
boost::bind( func, foo, _1 );
}
Если шаблон не является предпочтительным, то вы должны использовать какое-то удаление типа, например, снова boost::function
,
void SomeOtherFunction(boost::function<double(Foo&, int)> const& func);
(еще раз другой boost::function
типы возможны в зависимости от деталей, таких как передача ref-to-const, а не ref-to-non-const)
Попробуй это:
boost::bind(&Foo::f1, object, _1, _2);
object
это экземпляр класса Foo.
_1 и _2 являются заполнителями аргументов.