FireEmissary

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  14 随笔 :: 0 文章 :: 20 评论 :: 0 Trackbacks
我正设计一个布局类,对于托管的对象自动计算更新后的布局位置后调用用户的回调函数.bind用得非常high,然后最后却编译不过.
抽象出来就是如下代码:
#include <iostream>
#include 
<boost/bind.hpp>
#include 
<boost/function.hpp>
class test1
{
public:
    template
<typename S>
    
double handle(S s)
    {
        s(
1);
        std::cout
<<"test1\n";
        
return 1;
    }
    template
<typename F>
    
void handle1(F f)    {
boost::bind(
&test1::handle<F>,this,f)();//这里
    }

};
class test2
{
public:
    
double handle(int i)
    {
        std::cout
<<"test2\n";
        
return i;
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    test2 t2;
    test1 t1;

    t1.handle1(boost::bind(
&test2::handle,t2,_1));
    
return 0;
}
原来,bind为了支持
boost::bind(  std::logical_and<bool>(),     boost::bind(std::greater<int>(),_1,5),   boost::bind(std::less_equal<int>(),_1,10));
这类操作,内部自动对bind_t(即bind的返回类型)调用取得结果来作参数.代价就是不能把bind_t作为参数了.解决方法是,boost::ref包起来
boost::bind(&test1::handle<F>,this,boost::ref(f))();

boost user mail list有人建议
boost::bind(&test1::handle<boost::_bi::protected_bind_t<F>
>,this, protect(f))();
不过我认为用户还是别去接触boost::_bi空间来的好


另一件事是:bind返回的对象支持多于它本该支持的参数.同样上面的例子,改为
boost::bind(&test1::handle<F>,this,boost::ref(f))(1,2,3,4,5);
照样编译通过.带来的好处就是像boost::asio这样的库接受的回调可以很灵活,你要不要boost::system::error_code,bytes_transferred都没问题.asio::io_service总是压入所有必须的参数来进行回调,而被bind后的回调对象会只抽取自己必须的参数.

posted on 2011-03-16 12:56 FireEmissary 阅读(3042) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理