输入流上基于范围的循环

编程入门 行业动态 更新时间:2024-10-23 23:24:48
本文介绍了输入流上基于范围的循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

要遍历输入流,通常会像这样使用std::istream_iterator:

To iterate over an input stream, we would usually use a std::istream_iterator like so:

typedef std::istream_iterator<std::string> input_iterator; std::ifstream file("myfile"); for (input_iterator i(file); i != input_iterator(); i++) { // Here, *i denotes each element extracted from the file }

如果我们可以使用基于范围的for语句来迭代输入流,那就太好了.但是,对于类类型的对象,基于范围的for要求对象具有begin()和end()成员函数(第6.5.4节,添加了粗体):

It'd be nice if we could use the range-based for statement to iterate over input streams. However, for objects of class type, range-based for requires the object to have begin() and end() member functions (§6.5.4, bold emphasis added):

  • 如果_RangeT是数组类型,则 begin-expr 和 end-expr 分别是__range和__range + __bound,其中是数组绑定.如果_RangeT是未知大小的数组或类型不完整的数组,则程序格式错误;

    • if _RangeT is an array type, begin-expr and end-expr are __range and __range + __bound, respectively, where __bound is the array bound. If _RangeT is an array of unknown size or an array of incomplete type, the program is ill-formed;

      如果_RangeT是类类型,则在好像按类成员访问查找(3.4.5),并且如果一个(或两个)都找到至少一个声明,则 begin-expr 和 end-expr 为__range.begin()和__range.end()分别;

      if _RangeT is a class type, the unqualified-ids begin and end are looked up in the scope of class _RangeT as if by class member access lookup (3.4.5), and if either (or both) finds at least one declaration, begin-expr and end-expr are __range.begin() and __range.end(), respectively;

      否则, begin-expr 和 end-expr 分别为begin(__range)和end(__range),其中begin和end与参数相关的查找(3.4.2).出于此名称查找的目的,名称空间std是关联的名称空间.

      otherwise, begin-expr and end-expr are begin(__range) and end(__range), respectively, where begin and end are looked up with argument-dependent lookup (3.4.2). For the purposes of this name lookup, namespace std is an associated namespace.

      输入流不具有这些成员函数(它们不是Container),因此基于范围的for不适用于它们.无论如何,这是有道理的,因为您将需要某种方式来指定要提取的类型(在上述情况下为std::string).

      The input streams don't have these member functions (they are not Containers) and so range-based for won't work on them. This makes sense anyway because you would need some way to specify the type to extract (std::string in the case above).

      但是,如果我们知道要提取的内容,是否可以为输入流定义我们自己的begin()和end()函数(也许是std::begin()和std::end()的特殊化或重载),以便如上所述由类成员访问查找找到?

      But if we know what we want to extract, is it possible to define our own begin() and end() functions (perhaps specializations or overloads of std::begin() and std::end()) for input streams such that they would be found by class member access lookup as described above?

      从6.5.4节开始(至少对我而言)尚不清楚,如果先前的查找失败,那么是否将使用依赖于参数的查找来查找函数.要考虑的另一件事是,std::ios_base及其派生词已经有一个名为end的成员,该成员是进行搜索的标志.

      It's unclear (at least to me) from §6.5.4 whether the functions will then be looked up with argument-dependent lookup if the previous lookup fails. Another thing to consider is that std::ios_base and its derivatives already have a member called end which is a flag for seeking.

      这是预期的结果:

      std::ifstream file("myfile"); for (const std::string& str : file) { // Here, str denotes each element extracted from the file }

      或者:

      std::ifstream file("myfile"); for (auto i = begin(file); i != end(file); i++) { // Here, *i denotes each element extracted from the file }

      推荐答案

      一种显而易见的方法是为流使用简单的装饰器,以提供类型和必要的接口.这是这样的样子:

      An obvious approach is to use a simple decorator for your stream providing the type and the necessary interface. Here is how this could look like:

      template <typename T> struct irange { irange(std::istream& in): d_in(in) {} std::istream& d_in; }; template <typename T> std::istream_iterator<T> begin(irange<T> r) { return std::istream_iterator<T>(r.d_in); } template <typename T> std::istream_iterator<T> end(irange<T>) { return std::istream_iterator<T>(); } for (auto const& x: irange<std::string>(std::ifstream("file") >> std::skipws)) { ... }

更多推荐

输入流上基于范围的循环

本文发布于:2023-11-24 03:32:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1623821.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!