boost::bind() связывает дополнительные аргументы?
Связывает ли boost::bind() bind дополнительные аргументы, так как кажется, что передача функции bind без аргументов в один, ожидающий двойной аргумент, работает нормально? Если бы я должен был явно написать функцию связывания, что это должно быть?
struct MyClass
{
void f()
{
std::cout << "f()" << std::endl;
}
};
void bar( const boost::function<void(const double&)>& f )
{
f( 1.0 );
}
int main()
{
MyClass c;
// why this compiles
bar( boost::bind( &MyClass::f, &c ) );
// what should I write if I want to create the binded function explicitly before pass into bar?
// boost::function<void(const double&)> f = boost::bind( ... boost::bind( &MyClass::f, &c ), ?? )
bar( f );
}
1 ответ
Это по конструкции, несвязанные параметры (например, 1.0
), переданные при вызове bind-выражения, просто игнорируются.
boost::function<void(const double&)> f = boost::bind(&MyClass::f, &c);
bar(f);
было бы хорошо для явного назначения выражения связывания.
Обновление к комментарию:
Помните, два руководства:
function<...>
имеет фиксированную подписьbind
выражения не имеют фиксированной подписи. Вся цельbind
это изменить подпись. Это включает в себя, например,- добавление состояния для заполнения формальных параметров, удаленных из подписи или
- добавление параметров, которые следует игнорировать, не привязывая их к целевой вызываемой
- изменение типа аргумента / возврата с помощью неявных преобразований
- даже изменение порядка, в котором параметры привязаны к вызываемой цели, в то время как подпись технически может быть неизменной.
Так что пока вы не можете назначить разные func<...>
типы друг к другу, вы всегда можете bind
одна подпись другой.
Вот более полная демонстрация, которая показывает границы того, что вы можете сделать с function
а также bind
и почему (как он себя ведет): Live On Coliru:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <cassert>
int foo0() { return 0; }
int foo1(int) { return 1; }
int foo2(int,int) { return 2; }
int foo3(int,int,int) { return 3; }
int main()
{
boost::function<int()> func0;
boost::function<int(int)> func1;
boost::function<int(int,int)> func2;
boost::function<int(int,int,int)> func3;
// "straight" assignment ok:
// -------------------------
func0 = foo0; assert (0 == func0());
func1 = foo1; assert (1 == func1(-1));
func2 = foo2; assert (2 == func2(-1,-1));
func3 = foo3; assert (3 == func3(-1,-1,-1));
// "mixed" assignment not ok:
// --------------------------
// func0 = foo1; // compile error
// func3 = foo2; // compile error
// func1 = func2; // compile error, just the same
// func2 = func1; // compile error, just the same
// SOLUTION: you can always rebind:
// --------------------------------
func0 = boost::bind(foo3, 1, 2, 3); assert (func0() == 3);
func3 = boost::bind(foo1, _3); assert (func3(-1,-1,-1) == 1);
func3 = boost::bind(foo2, _3, _2); assert (func3(-1,-1,-1) == 2);
// same arity, reversed arguments:
func3 = boost::bind(foo3, _3, _2, _1); assert (func3(-1,-1,-1) == 3);
// can't bind more than number of formal parameters in signature:
// --------------------------------------------------------------
// func3 = boost::bind(foo1, _4); // in fact, the bind is fine, but assigning to `func3` fails
}
Все утверждения проходят. Вы можете попробовать то, что говорит компилятор, когда вы раскомментируете строки, которые не компилируются.
ура