在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的拷贝。