亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使我的自定義類型使用“基于范圍的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的范圍內查找unquali?ed-id開始和結束,就好像通過類成員訪問查找(3.4.5)一樣,并且如果其中一個(或兩者都)?nds至少有一個聲明、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 關注
  • 678 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號