与参数绑定

时间:2011-04-30 13:07:04

标签: c++ templates boost binding

我有绑定参数的功能问题。 Invoker类调用函数,它不知道参数。所以我不能在绑定中使用占位符,如:

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

我想做这样的事情:

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

我需要它,因为我想将函数A::fun传递给B::BFunB::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 个答案:

答案 0 :(得分:1)

好问题!

这里有两个问题。

问题1:bind作为参数传递给bind时,会得到一个函数组合:评估内部绑定的结果并传递给外部绑定为参数。请参阅documentation。要解决此问题,您应该使用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));

现在编译得很好。