c – 从std :: copy和std :: copy_n中提取输入迭代器

c – 从std :: copy和std :: copy_n中提取输入迭代器,第1张

概述我试图实现一个反序列化方法,它接受一个输入迭代器并执行一系列块读取(使用std :: copy和std :: copy_n).像这样的东西(只是一个例子): template <class InputIt>InputIt unserialize(InputIt it){ std::copy_n(it, sizeof(header_type), reinterpret_cast<char*> 我试图实现一个反序列化方法,它接受一个输入迭代器并执行一系列块读取(使用std :: copy和std :: copy_n).像这样的东西(只是一个例子):
template <class inputIt>inputIt unserialize(inputIt it){  std::copy_n(it,sizeof(header_type),reinterpret_cast<char*>(&header));  std::copy_n(it,header.payload_size,std::back_inserter(payload));  it = optional.unserialize(it);  return it;}

在这种情况下如何提前输入迭代器,以便每次跟随std :: copy_n的调用继续从中读取并最终返回它?

出于性能原因,我希望对迭代器类别(尤其是RandomAccessIterator和inputIterator)具有通用性,并希望可以使用std :: copy方法而无需重写这些方法.像绑定检查这样的东西将由迭代器适配器完成,或者如果已知大小,则在反序列化调用之前检查.

什么不起作用也不可接受:

>使用std :: copy_n< inputIt&>(it,…)可能适用于某些类别但不适用于所有类别,而且它太不可靠.
>在每次调用后使用std :: advance会导致为某些迭代器重新读取相同的块.不是优选的,对某些来源可能是不可能的.

更新使迭代器引用适配器没有帮助随机访问迭代器版本的copy_n返回指向复制的最后一个元素,而输入迭代器版本返回指向复制的最后一个元素的指针.所以我猜我自己的copy_n版本最适合使用额外的迭代器适配器进行绑定检查.

解决方法 对于 random access iterator,可以使用此表格 – 这很好:
template <class inputIt,class N,class OutputIt>inputIt copy_n_advance_input(inputIt it,N dist,OutputIt outIt){    std::copy_n(it,dist,outIt);    return std::next(it,dist);}

不幸的是 – 问题在于我们想要处理一个通道输入迭代器 – 就像这里(得到’d’ – 不是’c’):

std::string s = "abcd";std::istringstream ss{s};auto e = copy_n_advance_input(std::istream_iterator<char>(ss),2,std::ostream_iterator<char>(std::cout,","));std::cout << "\n" << *e << "\n";

所以似乎需要像STL一样需要两种形式:

template <class inputIt,class OutputIt>inputIt copy_n_advance_input_impl(inputIt it,OutputIt outIt,std::input_iterator_tag){    while (dist-- > 0)    {        *outIt = *it;        ++outIt;        ++it;    }    return it;}template <class inputIt,std::random_access_iterator_tag){    std::copy_n(it,dist);}template <class inputIt,OutputIt outIt){    return copy_n_advance_input_impl(it,outIt,typename std::iterator_traits<inputIt>::iterator_category {});}

注意,std :: input_iterator_tag的建议版本效率不如STL(至少对于gcc) – 它为输入做了额外的迭代 – 这次迭代不需要执行复制 – 但是需要返回“之后”的开头复制“range(stl_algo.h):

754   template<typename _inputIterator,typename _Size,typename _OutputIterator>755     _OutputIterator756     __copy_n(_inputIterator __first,_Size __n,757          _OutputIterator __result,input_iterator_tag)758     {759       if (__n > 0)760     {761       while (true)762         {763           *__result = *__first;764           ++__result;765           if (--__n > 0)766         ++__first;767           else768         break;769         }770     }771       return __result;772     }

最后一点 – 对于随机访问迭代器(如std :: vector :: iterator),使用std算法的版本更为明智 – 因为它们可以更加优化 – 例如对于POD类型的连续内存迭代器 – 可以只是memcpy’IEd.或者std :: vector< bool>的一些特化或者std :: deque< T>存在,使用其内部结构以最有效的方式执行复制.

总结

以上是内存溢出为你收集整理的c – 从std :: copy和std :: copy_n中提取输入迭代器全部内容,希望文章能够帮你解决c – 从std :: copy和std :: copy_n中提取输入迭代器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1240021.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存