boost::assign的用法淺析

在boost中看到這樣的代碼:

#include <boost/assign/std/vector.hpp> // for 'operator+=()'
#include <boost/assert.hpp>; 
using namespace std;
using namespace boost::assign; // bring 'operator+=()' into scope
{
    vector<int> values;  
    values += 1,2,3,4,5,6,7,8,9; // insert values at the end of the container
    BOOST_ASSERT( values.size() == 9 );
    BOOST_ASSERT( values[0] == 1 );
    BOOST_ASSERT( values[8] == 9 );
}
用+=操作符對std::vector進行復制。

查看boost::assign庫源碼,知道上面其實內部的技巧在於兩種操作符的重載:

1. vector.hpp文件中重載了operator +=(...)函數,傳入的參數有SLT container,和另一個它所支持的valueType。返回值類型是一個代理模板類: list_inserter。這個操作符+=重載對應上面的values += 1代碼段;

2. 然後接着就是operator ,(...)重載函數,因爲前面+=操作符重載返回list_inserter類型,而list_inserter模板類定義了operator ,(...)函數,返回值類型仍然是自己的引用list_inserter&,這樣的話就可以繼續跟着調用operator,(...)函數。


類似的代碼段還有如下:

#include <boost/assign/list_inserter.hpp> // for 'insert()'
#include <boost/assert.hpp> 
#include <string>
using namespace std;
using namespace boost::assign; // bring 'insert()' into scope
 
{
    map<string,int> 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 );
    BOOST_ASSERT( months.size() == 12 );
    BOOST_ASSERT( months["january"] == 31 );
} 
insert(container&)返回list_inserter,然後調用它的list_inserter& operator ()(...)函數(共提供最多5個,可配置)。

deque<int> di;    
push_front( di ) = 1,2,3,4,5,6,7,8,9;
BOOST_ASSERT( di.size() == 9 );    
BOOST_ASSERT( di[0] == 9 ); 
push_front(container&)返回list_inserter,然後調用它的list_inserter& operator=(...)函數,可以繼續調用list_inserter& operator,(...)函數。

#include <boost/assign/list_of.hpp> // for 'list_of()'
#include <boost/assert.hpp> 
#include <list>
#include <stack>
#include <string>
using namespace std;
using namespace boost::assign; // bring 'list_of()' into scope
 
{
    const list<int> primes = list_of(2)(3)(5)(7)(11);
    BOOST_ASSERT( primes.size() == 5 );
    BOOST_ASSERT( primes.back() == 11 );
    BOOST_ASSERT( primes.front() == 2 );
   
    const stack<string> names = list_of( "Mr. Foo" )( "Mr. Bar")( "Mrs. FooBar" ).to_adapter();
    const stack<string> names2 = (list_of( "Mr. Foo" ), "Mr. Bar", "Mrs. FooBar" ).to_adapter();
    BOOST_ASSERT( names.size() == 3 );
    BOOST_ASSERT( names.top() == "Mrs. FooBar" );
}   
list_of(...)函數返回一個generic_list臨時對象,之後調用generic_list& generic_list::operator()(...)函數,之後便迭代調用。最後調用成員模板函數template <typename Container> operator Container() const將generic_list轉化爲一個STL container。注意此時返回的是一個container的拷貝。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章