为了账号安全,请及时绑定邮箱和手机立即绑定

如何使我的自定义类型使用“基于范围的for循环”?

如何使我的自定义类型使用“基于范围的for循环”?

C++
慕桂英4014372 2019-07-10 14:42:36
如何使我的自定义类型使用“基于范围的for循环”?像现在很多人一样,我一直在尝试C+11带来的不同特性。我最喜欢的一个是“基于范围的循环”。我知道:for(Type& v : a) { ... }相当于:for(auto iv = begin(a); iv != end(a); ++iv){   Type& v = *iv;   ...}而那begin()简单地返回a.begin()标准容器。但如果我想使我的自定义类型“基于范围的for循环”-感知 ?我是不是应该专攻begin()和end() ?如果我的自定义类型属于命名空间xml,我是否应该定义xml::begin()或std::begin() ?简言之,这方面的指引是甚麽?
查看完整描述

3 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

标准的相关部分为6.5.4/1:

如果_RangeT是类型,则在class_RangeT的范围内查找unqualified-id开始和结束,就好像通过类成员访问查找(3.4.5)一样,并且如果其中一个(或两者都)finds至少有一个声明、BEG-Exr和End-Exr是__range.begin()__range.end()分别;

-否则,开始-支出和结束-费用是begin(__range)end(__range),分别使用依赖于参数的查找(3.4.2)查找开始和结束的位置。出于这个名称查找的目的,命名空间std是一个关联的命名空间。

因此,您可以执行以下任何操作:

  • 定义

    begin

    end

    成员函数
  • 定义

    begin

    end

    ADL将找到的免费函数(简化版本:将它们与类放在同一个名称空间中)
  • 专门性

    std::begin

    std::end

std::begin调用begin()成员函数,所以如果您只实现上面的一个,那么不管您选择哪一个,结果都应该是相同的。对于基于范围的for循环来说,这是相同的结果,对于没有自己神奇的名称解析规则的凡间代码也是如此。using std::begin;然后是一个无条件的呼叫begin(a).

如果您实现了成员函数然而,ADL函数,则基于范围的for循环应该调用成员函数,而只有凡人才会调用ADL函数。最好确保他们在这种情况下做同样的事情!

如果您正在编写的东西实现了容器接口,那么它将有begin()end()成员函数已经完成,这应该足够了。如果它不是一个容器的范围(如果它是不可变的,或者如果您不知道前面的大小),那么您可以自由选择。

在您列出的选项中,请注意绝不能过载std::begin()..您可以为用户定义的类型专门化标准模板,但除此之外,向命名空间std添加定义是未定义的行为。但是无论如何,专门化标准函数是一个糟糕的选择,因为缺少部分函数专门化意味着您只能对单个类进行专门化,而不能对类模板进行专门化。


查看完整回答
反对 回复 2019-07-10
?
炎炎设计

TA贡献1808条经验 获得超4个赞

我写我的答案是因为有些人可能更喜欢简单的现实生活中没有STL包含的例子。

出于某种原因,我有自己的纯数据数组实现,我想使用基于范围的for循环。这是我的解决方案:

 template <typename DataType>
 class PodArray {
 public:
   class iterator {
   public:
     iterator(DataType * ptr): ptr(ptr){}
     iterator operator++() { ++ptr; return *this; }
     bool operator!=(const iterator & other) const { return ptr != other.ptr; }
     const DataType& operator*() const { return *ptr; }
   private:
     DataType* ptr;
   };
 private:
   unsigned len;
   DataType *val;
 public:
   iterator begin() const { return iterator(val); }
   iterator end() const { return iterator(val + len); }

   // rest of the container definition not related to the question ...
 };

然后是用法示例:

PodArray<char> array;// fill up array in some wayfor(auto& c : array)
  printf("char: %c\n", c);


查看完整回答
反对 回复 2019-07-10
  • 3 回答
  • 0 关注
  • 644 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信