std::transform,std::back_inserter的小配合

下面是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)的++是怎么重载的呢?

  1. container为Container对象,即Container container
  2. back_inserter(container)实际为back_insert_iterator< Container>,其++为*(this),即返回自身
  3. back_insert_iterator< Container>的operator=为container->push_back

所以综上所述,back_inserter为模板函数,其作用是构造一个back_insert_iterator对象,该对象中有container,通过重载=与++等实现对变量的push_back。所以使用时

  1. 首先要有一个容器 ,其支持push_back。
  2. 配合其他算法函数一起使用,通过=插入,比如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; }
    };

可以看出:

  1. back_insert_iterator的++是等于自己
  2. back_insert_iterator的*也是等于自己
  3. 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值