相信大多數使用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 )
操作符+=已被過載,它的任務是返回乙個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 )
這裡的call_push_back(c)實際是建立乙個類call_push_back的例項,以使生成的list_inserter能夠知道自己該怎樣進行操作。
template< class c >
class call_push_back
template
< class t > void
operator()( t r )
};
make_list_inserter和stl中的make_pair類似,都是用於包裝實現類的,真正的實現是利用list_inserter。
template< class function, class argument >
inline list_insertermake_list_inserter( function fun, argument* )
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& operator()()
template
< class t >
list_inserter& operator,( const t& r )
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,實現與此類似。
STL原始碼剖析之序列式容器
最近由於找工作需要,準備深入學習一下stl原始碼,我看的是侯捷所著的 stl原始碼剖析 之所以看這本書主要是由於我過去曾經接觸過一些台灣人,我一直覺得台灣人非常不錯 這裡不涉及任何政治,僅限個人感受 在技術上他們比較嚴謹,在為人處世上也非常謙虛,所以一些台灣的技術資料我覺得是值得一看的。想要學習st...
STL原始碼剖析 容器 RB tree
rb tree,全稱是red black tree,又稱為 紅黑樹 紅黑樹本質上是一種二叉查詢樹,但它在二叉查詢樹的基礎上額外新增了乙個標記 顏色 同時具有一定的規則。這些規則使紅黑樹保證了一種平衡,插入 刪除 查詢的最壞時間複雜度都為o logn 每個節點不是紅色就是黑色 根結點永遠都是黑色 所有...
STL原始碼剖析 容器 vector
vector 常被稱為向量容器,因為該容器擅長在尾部插入或刪除元素,在常量時間內就可以完成,時間複雜度為o 1 而對於在容器頭部或者中部插入或刪除元素,則花費時間要長一些 移動元素需要耗費時間 時間複雜度為線性階o n vector實現的關鍵在於其對大小的控制以及重新配置時的資料移動效率。vecto...