Boost源码剖析之assignment

Boost.assignment库的使用及简单分析

相信大多数使用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 );

分析assignment的源代码,先看 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 );

}


//assign/List_inserter.hpp:


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 );

}


template
< class Function, class Argument >

inline
list_inserter

make_list_inserter( Function fun, Argument* )

{


return
list_inserter ( fun );

}


重载了+=操作符,所以才有 i_v+=1,2,3,4,5 这种写法。可以看出 push_back函数返回一个list_inserter,对应例子,push_back(c)(v)即为push_back(i_v)(1),返回一个仿函数list_inserter <:call_push_back ="">>, int>(assign_detail::call_push_back(i_v))(1) 。 那数字间的逗号又是怎么处理的呢?不知道大家还记不记得 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 )

{}

....


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 ), 看看
:

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 );

}

};
实际是调用了c.push_back(r),对应到上面的例子,也就是调用了 i_v.push_back(1) 。 至于map的insert,实现与此类似。

相关文章

分类

留言:

关于文章

This page contains a single entry by DongHao published on 08 15, 2007 6:42 PM.

Python , Delphi , Loki 有趣的来源 was the previous entry in this blog.

shell命令:操作数量较大的文件 is the next entry in this blog.

Find recent content on the main index or look in the 存档 to find all content.