下面是fast-rtps里的一段代码
do
{
// copy ordinary locators till the first ANY
old_it = it;
it = std::find_if(it, UnicastLocatorList.end(), IPLocator::isAny);
// copy ordinary locators
std::copy(old_it, it, std::back_inserter(unicast_real_locators));
// transform new ones if needed
if (it != UnicastLocatorList.end())
{
const Locator_t& an_any = *it;
// load interfaces if needed
if (locals.empty())
{
IPFinder::getIP4Address(&locals);
}
// add a locator for each local
std::transform(locals.begin(),
locals.end(),
std::back_inserter(unicast_real_locators),
[&an_any](const Locator_t& loc) -> Locator_t
{
Locator_t specific(loc);
specific.port = an_any.port;
specific.kind = an_any.kind;
return specific;
});
// search for the next if any
++it;
}
} while (it != UnicastLocatorList.end());
这里使用了transform配合back_inserter,transform的代码如下
transform本身是实现将first和last迭代器中的值传入op中处理,返回的值放入result迭代器中
看下面代码1,result是需要++的,但是back_inserter(container)的++是怎么重载的呢?
- container为Container对象,即Container container
- back_inserter(container)实际为back_insert_iterator< Container>,其++为*(this),即返回自身
- back_insert_iterator< Container>的operator=为container->push_back
所以综上所述,back_inserter为模板函数,其作用是构造一个back_insert_iterator对象,该对象中有container,通过重载=与++等实现对变量的push_back。所以使用时
- 首先要有一个容器 ,其支持push_back。
- 配合其他算法函数一起使用,通过=插入,比如std::copy,std::transform等
template<typename _InputIterator, typename _OutputIterator,
typename _UnaryOperation>
_GLIBCXX20_CONSTEXPR
_OutputIterator
transform(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _UnaryOperation __unary_op)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
// "the type returned by a _UnaryOperation"
__typeof__(__unary_op(*__first))>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first, (void)++__result) // 1
*__result = __unary_op(*__first); // 2
return __result;
}
咱们来看下back_inserter的源码,主要看其几个operator,重点关注下++和=
template<typename _Container>
_GLIBCXX20_CONSTEXPR
inline back_insert_iterator<_Container>
back_inserter(_Container& __x) // 1
{ return back_insert_iterator<_Container>(__x); }
explicit _GLIBCXX20_CONSTEXPR
back_insert_iterator(_Container& __x) // 2
: container(std::__addressof(__x)) { }
_GLIBCXX20_CONSTEXPR
back_insert_iterator&
operator=(const typename _Container::value_type& __value)
{
container->push_back(__value);
return *this;
}
_GLIBCXX20_CONSTEXPR
back_insert_iterator&
operator=(typename _Container::value_type&& __value)
{
container->push_back(std::move(__value));
return *this;
}
#endif
/// Simply returns *this.
_GLIBCXX20_CONSTEXPR
back_insert_iterator&
operator*()
{ return *this; }
/// Simply returns *this. (This %iterator does not @a move.)
_GLIBCXX20_CONSTEXPR
back_insert_iterator&
operator++()
{ return *this; }
/// Simply returns *this. (This %iterator does not @a move.)
_GLIBCXX20_CONSTEXPR
back_insert_iterator
operator++(int)
{ return *this; }
};
可以看出:
- back_insert_iterator的++是等于自己
- back_insert_iterator的*也是等于自己
- back_inserter的operator=是调用container的push_back,所以需要支持push_back的容器,back_inserter构造函数本身只是拿到了container的指针,其目的是为了后续比如调用 back_inserter(va) = 5时,调用push_back。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> va={1,2};
*va.end() = 3; //no use
*back_inserter(va) = 4;
back_inserter(va) = 5;
for(auto a:va)
cout<<a<<endl;
}
1
2
4
5