程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++11的for輪回,和規模Range類的簡略完成

C++11的for輪回,和規模Range類的簡略完成

編輯:關於C++

C++11的for輪回,和規模Range類的簡略完成。本站提示廣大學習愛好者:(C++11的for輪回,和規模Range類的簡略完成)文章只能為提供參考,不一定能成為您想要的結果。以下是C++11的for輪回,和規模Range類的簡略完成正文


C++11支撐range-based for輪回。這是一個很便利的特征,能省挺多代碼。以下代碼就可以很便利的遍歷vector中的元素,並打印出來:

std::vector<int> int_vec;

int_vec.push_back(1);

int_vec.push_back(2);

//假如要修正int_vec中的元素,將變量x聲明為 int& 便可

for (int x: int_vec)

{

 std::cout << x << endl;

}

可以遍歷的對象包含:

•數組。(不包含指針)
•界說了begin()和end()辦法,且前往該辦法前往迭代器的類對象。(STL 中一切容器都可以)

(關於靜態生成的數組的遍歷,用上面引見的Range類也能省很多代碼)

參考 http://en.cppreference.com/w/cpp/language/range-for 可知,

語句 for ( range_declaration : range_expression) loop_statement

與以下語句感化等價:

{ 

 auto && __range = range_expression ; 

 for (auto __begin = begin_expr, 

   __end = end_expr;

   __begin != __end; ++__begin) {

  range_declaration = *__begin; 

 loop_statement

 } 

}

關於可遍歷的類對象,__begin和__end分離由類的begin()和end()辦法發生。且因為__range變量是右值援用,假如range_expression的成果是右值,其將會在輪回停止後析構。

--------------------------------------------------------------------------------

如許,C++11終究支撐了這類古代編程說話都支撐的遍歷方法了。然則,不管是語法照樣尺度庫都不支撐對詳細數字的遍歷,好比python中的 for i in xrange(1,5)語句中,x將持續取[1,4]中的值。(Boost庫有irange類可以知足這個需求,然則上面會評論辯論下我的完成)

最直接的辦法,就是寫一個函數,前往一個vector<int>對象,其元素為從begin到end的值。但如許每次輪回時都得結構一個如許的對象,略慢。

從尺度來看,假如一個類要支撐如許遍歷,至多得有begin()和end()辦法。在for輪回的初始化部門,挪用了這兩個辦法以後,就沒這個類啥事了——都是迭代器的事。所以很天然,從迭代器高低手。這個迭代器必需支撐三種操作:!=,前綴++,解援用
。有沒發明,假如這個“迭代器”是個int數值的話,下面輪回中的__begin!=__end;++__begin語句就是一個異常天然的完成。如今的目的很簡略了:這個“迭代器”不遍歷容器中的每一個元素,而就是一個簡略的int數值的封裝。對其解援用將前往這個數

,而比擬和自加操作均對這個數停止操作。

--------------------------------------------------------------------------------

有設法主意以後,完成起來就很輕易了。起首界說一個仿迭代器 FakeIter ,其對一個數值停止封裝,偏重載必需的操作符。

class FakeIter

{

 typedef long _VType; //數值的類型為long。固然了,也能夠寫個模板出來

public:

 

 explicit FakeIter(_VType val)

  :value_(val){}

 

 bool operator != (const FakeIter& other) const

 {

  return (this->GetValue()) != (other.GetValue());

 }

 _VType operator* () const

 {

  return GetValue();

 }

 const FakeIter& operator++ ()

 {

  ++value_;

  return *this;

 }

private:

 _VType GetValue() const

 {

  return value_;

 }

 _VType value_;

};

至於“容器”類的完成,就更簡略了:完成begin()和end()辦法,並前往下面的FakeIter就行了。類中的辦法加了一些cout語句,可以更清晰的懂得輪回履行時詳細辦法的挪用進程,現實用時可以刪失落。

 
class Range

{

 typedef long _VType; //異樣,也能夠弄個模板出來,然則就不便利用了

public:

 Range (_VType begin_v, _VType end_v)

  :begin_value_(begin_v), end_value_(end_v)

 {

  cout<<"Range::Range()"<<endl;

 }

 ~Range()

 {

  cout<<"Range::~Range()"<<endl;

 }

 

 FakeIter begin () const

 {

  cout<<"Range::begin()"<<endl;

  return FakeIter(begin_value_);

 }

 FakeIter end () const

 {

  cout<<"Range::end()"<<endl;

  return FakeIter(end_value_ );

 }

private:

 _VType begin_value_;

 _VType end_value_;

}; 

好了,嘗嘗看這貨有沒用:

for (auto x: Range(1,5))

{

 std::cout<<x<<endl;

}

std::cout<<"Loop end"<<endl;

在vs2012及clang下輸入以下:

Range::Range() 
Range::begin() 
Range::end() 
1 
2 
3 
4 
Range::~Range() 
Loop end

嗯,假如把那些影響視野的輸入語句的正文失落的話貌似能用了。如今要遍歷一個new生成的數組的話,只需用這器械Range個下標,世界就僻靜了。

然則,步長呢!好吧,貌似我臨時還沒這方面的需求。不外完成起來也很簡略:修正FakeIter類便可以了,可以增長一個表現步長的成員,然後再修正自加操作。更進一步,也能夠加一個生成器辦法,就可以釀成一個更通用的生成器了。合營C++11 lambda操作符,用起來也挺便利。

以上就是小編為年夜家帶來的C++11的for輪回,和規模Range類的簡略完成全體內容了,願望年夜家多多支撐~

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved