Boost源码剖析之:容器赋值-assign
来源:互联网 发布:网络购物用户规模 编辑:程序博客网 时间:2024/06/14 22:12
相信大多数使用STL的人都是为了使用里面的容器,使用vector、list、map的程序员对以下代码可以说是非常熟悉了:
vector i_v;i_v.push_back(1);i_v.push_back(2);i_v.push_back(3);i_v.push_back(4);i_v.push_back(5);
挺枯燥,是吧?用boost的assignment库可以让这一过程简洁得多:
#include "boost/assign/std/vector.hpp"using namespace boost::assign;vector i_v;i_v += 1,2,3,4,5;
效果与上面的程序一致,可读性却好很多,看上去有点“脚本语言”的感觉了。
对于关联容器,也有类似的便洁方法:
#include "boost/assign/list_inserter.hpp"#include "string"using namespace std;using namespace boost::assign;map months;insert( months )( "january", 31 )( "february", 28 )( "march", 31 )( "april", 30 )( "may", 31 )( "june", 30 )( "july", 31 )( "august", 31 )( "september", 30 )( "october", 31 )( "november", 30 )( "december", 31 );
分析assign的源代码,以vector为例,先看:
//assign/std/vector.hpp:template< class V, class A, class V2 >inline list_inserter< assign_detail::call_push_back< std::vector >, V >operator+=( std::vector & c, V2 v ){ return push_back( c )( v );}
操作符+=已被重载,它的任务是返回一个list_inserter类,这是assign中的核心类之一。再看push_back,它也没有实质性的动作,只是创建一个list_inserter然后返回它。
template< class C >inline list_inserter< assign_detail::call_push_back ,BOOST_DEDUCED_TYPENAME C::value_type >push_back( C& c ){ static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; return make_list_inserter( assign_detail::call_push_back ( c ), p );}
这里的call_push_back(c)实际是创建一个类call_push_back的实例,以使生成的list_inserter能够知道自己该怎样进行操作。
template< class C >class call_push_back{ C& c_; public: call_push_back( C& c ) : c_( c ) { } template< class T > void operator()( T r ) { c_.push_back( r ); }};
make_list_inserter和STL中的make_pair类似,都是用于包装实现类的,真正的实现是利用list_inserter。
template< class Function, class Argument >inline list_inserter<Function,Argument>make_list_inserter( Function fun, Argument* ){ return list_inserter<Function,Argument>( fun );}
list_inserter重载了+=操作符,所以才有 i_v+=1,2,3,4,5 这种写法。可以看出 push_back函数返回一个list_inserter,对应例子,i_v+=1变为push_back(i_v)(1),其中的push_back(i_v) (注意:不包括后面的“(1)”!) 变为make_list_inserter(call_push_back(i_v), 0),最后make_list_inserter返回的是list_inserter< call_push_back, int>实例,现在可以加上后面的“(1)”了,由于list_inserter重载了“()”操作符,所以此时值1才被list_inserter接收。
那数字间的逗号又是怎么处理的呢?大家还记不记得 std::cout<< 1 << 2 << 3; 此处的<<和assign中的逗号其实是一个道理,<<操作符返回一个iostream,而逗号操作符返回一个 list_inserter 。“+=”操作符返回第一个list_inserter,其它的逗号“跟进”:
template< class Function, class Argument = assign_detail::forward_n_arguments >class list_inserter{ list_inserter( Function fun ) : insert_( fun ) {} .... list_inserter& operator()() { insert_( Argument() ); return *this; } template< class T > list_inserter& operator,( const T& r ) { insert_( r ); return *this; } private: Function insert_;}
这里的insert_就是先前的assign_detail::call_push_back ( c ),所以insert_( r )就是 assign_detail::call_push_back ( c )( r )。
list_inserter还有repeat,repeat_fun,range等方法,分别对应assign中 i_v+=1,repeat(2,4),3....等写法的实现。针对vector的assign基本就是这样,至于map等其它容器的assign,实现与此类似。
- Boost源码剖析之:容器赋值-assign
- Boost源码剖析之:容器赋值-assign
- Boost源码剖析之:容器赋值-assign
- 转:Boost源码剖析之:容器赋值-assign
- (转)Boost源码剖析之:容器赋值-assign 收藏
- Boost assign赋值库
- boost之bind源码剖析
- boost源码剖析之any
- boost源码剖析之:boost::multi_array
- boost源码剖析之:boost::multi_array
- boost源码剖析之:boost::multi_array
- 《STL源码剖析》之容器
- 顺序容器:容器的赋值、swap、assign
- 顺序容器:容器的赋值、swap、assign
- boost源码剖析之:Tuple Types
- STL源码剖析学习之容器
- STL源码剖析之序列容器list
- STL源码剖析之序列容器deque
- C_语法概念_sizeof()功能:计算数据空间的字节数以及字节对齐问题
- Silverlight开发需安装的插件
- Boost源码剖析之:增强的std::pair--Tuple Types (二)
- c++中socket编程需要的类型转换函数
- ubuntu中的几种文件类型
- Boost源码剖析之:容器赋值-assign
- Oracle数据操作和控制语言详解(之一)
- 用Linq和Dataview筛选查询DataTable数据,DataTable和List相互转换
- git添加数字版本号
- VS2008远程调试
- Android PackageManagerService详细分析
- Oracle数据操作和控制语言详解(之二)
- 【转】备份Ubuntu的工具—Remastersys
- Boost.Signals用法详解