Связывание с параметрами - PullRequest
2 голосов
/ 30 апреля 2011

У меня проблема с привязкой параметров к функции. Функция вызова класса Invoker, и она не знает о параметрах. Поэтому я не могу использовать заполнители в привязке, как:

v.invoke(boost::bind(&B::fun, this, _1));

Я хочу сделать что-то вроде этого:

v.invoke(boost::bind(&B::fun, this, fun_p));

Мне это нужно, потому что я хочу передать функцию A::fun в B::BFun. B::BFun не должен вызывать напрямую A::fun, но с использованием B::fun.

class A
{
public:
A(){}
   void fun(){
       std::wcout << "FunA" << std::endl;
   }
};

class Invoker
{
public:
    Invoker(){}
   template <typename Handler>
   void invoke(Handler f)
   {
    f();
   }
};


class B
{
public:
B(){}

template <typename Handler>
void BFun(Handler fun_p)
{
    Invoker v;
    v.invoke(boost::bind(&B::fun, this, fun_p)); <------- how to pass param. Not      placeholder
}

template <typename Handler>
void fun(Handler func)
{
    func();
    std::wcout << "FunB" << std::endl;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
A a;
B b;
b.BFun(boost::bind(&A::fun, &a));
return 0;
}

1 Ответ

1 голос
/ 30 апреля 2011

Хороший вопрос!

У вас здесь две проблемы.

Проблема 1: при передаче bind в качестве параметра bind вы получаете композицию функции: результат внутреннего связывания оценивается и передается внешнему связыванию в качестве параметра. См. документацию . Чтобы решить эту проблему, вы должны обернуть свой функциональный параметр с помощью protect:

template <typename Handler>
void BFun(Handler fun_p)
{
    BFunImpl(boost::protect(fun_p));
}

template<tyename Handler>
void BFunImpl(Handler fun_p)
{
    Invoker v;
    v.invoke(boost::bind(&B::fun, this, fun_p));
}

Задача 2: вы берете адрес шаблона функции. Компилятор не знает, для какой функции создать экземпляр и взять адрес. Вы можете использовать static_cast для приведения к нужному типу или использовать явный синтаксис:

v.invoke(boost::bind(&B::template fun<Handler>, this, fun_p));

Теперь скомпилируется нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...