首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 操作系统 >

详细解析boost中bind的兑现

2012-07-31 
详细解析boost中bind的实现写在前面的话在C11之后,std::bind是C标准库的一个组件了。一开始想弄个C11的实现

详细解析boost中bind的实现
写在前面的话

在C++11之后,std::bind是C++标准库的一个组件了。一开始想弄个C++11的实现来研究下,发现里面用到了可变参数模板(代码变得非常神奇).

http://llvm.org/svn/llvm-project/libcxx/trunk/include/functional

还是弄个原始点的boost的实现来研究下。


话说网上关于boost::bind的实现的文章也有不少,不过大多数都是贴一段代码,再扯一通,结果到头来什么都没看明白。(起码LZ是。。)

花了一天的功夫,最终从boost::bind的源代码中抠出了可编绎运行的代码。

下面一步一步来解析boost::bind的实现。

标准库中的fouctor和bind1st的实现

首先从简单的入手。先看下标准库中的fouctor和bind1st的实现(为了防止和标准库的命名冲突,全部都在命名后面加了2)。

A1 operator[](boost::arg<1>) const {cout << "list2  A1 operator[](boost::arg<1>)" << endl;return base_type::a1_;}A2 operator[](boost::arg<2>) const {cout << "list2  A1 operator[](boost::arg<2>)" << endl;return base_type::a2_;}A1 operator[](boost::arg<1> (*)()) const {cout << "list2  A1 operator[](boost::arg<1> (*)())" << endl;return base_type::a1_;}A2 operator[](boost::arg<2> (*)()) const {cout << "list2  A1 operator[](boost::arg<2> (*)())" << endl;return base_type::a2_;}template<class T> T & operator[](_bi::value<T> & v) const {cout << "T & operator[](_bi::value<T> & v)" << endl;return v.get();}
貌似问题都解决了,其实这里还有一个关键要素,两个list2是怎么合并起来,组成正确的参数传递给函数f的?(第一个list2存放了123和_1,第二个list2存放了i1和i2)

传递给tow_arguments函数的参数实际是是(123, 1)!

这里要仔细研究这些operator[]函数的实现,才能真正理解其过程。


注意,上面的的代码中bind2只能绑定普通的函数,不能绑定类成员函数,functor,智能指针等。不过其实区别不大,只是增加一些特化的代码而已。

还有一些const相关的函数删掉了。

后记:

从代码可以看到boost::bind和原生的函数指针相比,会损失效率(两次的寻址,函数参数的拷贝,有一些可能没有inline的函数调用)。

不得不吐槽下boost的代码中那些神奇的宏,如果不是IDE有提示,我想真心弄不明白到底哪段是有意义的。。有时候还很神奇地include一部分代码进来(不是头文件,只是实现的一部分!)。

不得不吐槽下模板编程中的const,为了一个函数,比如int sum(int a, int b); 就得写四个重载函数来对应不同参数是或者不是const的情况。所以大家可以想像bind最多支持9个参数,那么有多少种情况了。

boost::bind的实现的确非常精巧,隐藏了很多复杂性。在《C++沉思录》中作者说到世界是复杂的,可以通过复杂性获取简单性。也许这个是对的,但是对于无数的后来的程序员总会有人想要看看黑盒子里到底是什么东东,结果总要花大量的时间才能理解,才能获得这种“简单性”。

C++的模板代码中最痛苦的是到处都是typedef,一个typedef就把所有的类型信息都干掉了!而这东东又是必须的。

也许C++给编程语言技术带来的最大贡献就是牛B的编译器了!

C++11中貌似部分的支持concept,希望这个能简化模板编程。

热点排行