C++11的for循環(huán),以及范圍Range類的簡(jiǎn)單實(shí)現(xiàn)
C++11支持range-based for循環(huán)。這是一個(gè)很方便的特性,能省挺多代碼。以下代碼就能很方便的遍歷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;
}
可以遍歷的對(duì)象包括:
•數(shù)組。(不包括指針)
•定義了begin()和end()方法,且返回該方法返回迭代器的類對(duì)象。(STL 中所有容器都可以)
(對(duì)于動(dòng)態(tài)生成的數(shù)組的遍歷,用下面介紹的Range類也能省不少代碼)
參考 http://en.cppreference.com/w/cpp/language/range-for 可知,
語句 for ( range_declaration : range_expression) loop_statement
與以下語句作用等價(jià):
{
auto && __range = range_expression ;
for (auto __begin = begin_expr,
__end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
對(duì)于可遍歷的類對(duì)象,__begin和__end分別由類的begin()和end()方法產(chǎn)生。且由于__range變量是右值引用,如果range_expression的結(jié)果是右值,其將會(huì)在循環(huán)結(jié)束后析構(gòu)。
--------------------------------------------------------------------------------
這樣,C++11終于支持了這種現(xiàn)代編程語言都支持的遍歷方式了。但是,無論是語法還是標(biāo)準(zhǔn)庫都不支持對(duì)具體數(shù)字的遍歷,比如python中的 for i in xrange(1,5)語句中,x將連續(xù)取[1,4]中的值。(Boost庫有irange類可以滿足這個(gè)需求,但是下面會(huì)討論下我的實(shí)現(xiàn))
最直接的方法,就是寫一個(gè)函數(shù),返回一個(gè)vector<int>對(duì)象,其元素為從begin到end的值。但這樣每次循環(huán)時(shí)都得構(gòu)造一個(gè)這樣的對(duì)象,略慢。
從標(biāo)準(zhǔn)來看,如果一個(gè)類要支持這樣遍歷,至少得有begin()和end()方法。在for循環(huán)的初始化部分,調(diào)用了這兩個(gè)方法之后,就沒這個(gè)類啥事了——都是迭代器的事。所以很自然,從迭代器上下手。這個(gè)迭代器必須支持三種操作:!=,前綴++,解引用
。有沒發(fā)現(xiàn),如果這個(gè)“迭代器”是個(gè)int數(shù)值的話,上面循環(huán)中的__begin!=__end;++__begin語句就是一個(gè)非常自然的實(shí)現(xiàn)。現(xiàn)在的目標(biāo)很簡(jiǎn)單了:這個(gè)“迭代器”不遍歷容器中的每個(gè)元素,而就是一個(gè)簡(jiǎn)單的int數(shù)值的封裝。對(duì)其解引用將返回這個(gè)數(shù)
,而比較和自加操作均對(duì)這個(gè)數(shù)進(jìn)行操作。
--------------------------------------------------------------------------------
有想法之后,實(shí)現(xiàn)起來就很容易了。首先定義一個(gè)仿迭代器 FakeIter ,其對(duì)一個(gè)數(shù)值進(jìn)行封裝,并重載必須的操作符。
class FakeIter
{
typedef long _VType; //數(shù)值的類型為long。當(dāng)然了,也可以寫個(gè)模板出來
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_;
};
至于“容器”類的實(shí)現(xiàn),就更簡(jiǎn)單了:實(shí)現(xiàn)begin()和end()方法,并返回上面的FakeIter就好了。類中的方法加了一些cout語句,可以更清楚的了解循環(huán)執(zhí)行時(shí)具體方法的調(diào)用過程,實(shí)際用時(shí)可以刪掉。
class Range
{
typedef long _VType; //同樣,也可以弄個(gè)模板出來,但是就不方便用了
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
嗯,如果把那些影響視線的輸出語句的注釋掉的話貌似能用了?,F(xiàn)在要遍歷一個(gè)new生成的數(shù)組的話,只需用這東西Range個(gè)下標(biāo),世界就清靜了。
但是,步長(zhǎng)呢!好吧,貌似我暫時(shí)還沒這方面的需求。不過實(shí)現(xiàn)起來也很簡(jiǎn)單:修改FakeIter類就可以了,可以增加一個(gè)表示步長(zhǎng)的成員,然后再修改自加操作。更進(jìn)一步,也可以加一個(gè)生成器方法,就能變成一個(gè)更通用的生成器了。配合C++11 lambda操作符,用起來也挺方便。
以上就是小編為大家?guī)淼腃++11的for循環(huán),以及范圍Range類的簡(jiǎn)單實(shí)現(xiàn)全部?jī)?nèi)容了,希望大家多多支持我們~
上一篇:DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--浮點(diǎn)數(shù)的存儲(chǔ)格式
欄 目:C語言
下一篇:DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--定點(diǎn)數(shù)模擬浮點(diǎn)數(shù)運(yùn)算及常見的策略
本文標(biāo)題:C++11的for循環(huán),以及范圍Range類的簡(jiǎn)單實(shí)現(xiàn)
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/2216.html
您可能感興趣的文章
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)式函數(shù)庫
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)數(shù)怎么表達(dá)
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 01-10c語言求1+2+...+n的解決方法
- 01-10求子數(shù)組最大和的解決方法詳解
- 01-10深入理解約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法
- 01-10深入二叉樹兩個(gè)結(jié)點(diǎn)的最低共同父結(jié)點(diǎn)的詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)- 解析最少換車次數(shù)的問題詳解
- 01-10c語言 跳臺(tái)階問題的解決方法
- 01-10如何判斷一個(gè)數(shù)是否為2的冪次方?若是,并判斷出來是多少次方


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10delphi制作wav文件的方法
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置


