2011-07-22 193 views
38

我一直在使用「加速C++」在暑假學習C++,並且有一個我似乎並沒有正確理解的概念。if(cin >> x) - 爲什麼你可以使用該條件?

爲什麼相當於

int x; 
if (cin >> x){} 

cin >> x; 
if (cin){} 

通過查看代碼,在我看來,我們正在使用CIN作爲變量。但是,我認爲這是一個功能。爲什麼我們可以用這種方式使用cin,當x是我們輸入到鍵盤的任何值時?

回答

51

cin是表示標準輸入流的類istream的對象。它對應於cstdiostdin。流的運算符>>重載對同一個流的引用。流本身可以通過轉換運算符在布爾條件中評估爲true或false。

cin提供格式化流提取。操作 cin >> x;

如果輸入的非數字值爲 ,其中「x」爲整數將失敗。所以:

if(cin>>x) 

將返回false如果您輸入一個字母而不是數字。

這個網站上tips and tricks using C++ I/O也會幫助你。

+0

對不起,這對我來說技術太過了。我沒有上過類或類似的東西。我們爲什麼要使用布爾值? –

+1

@Muhsin Ali:嘗試理解一個人在學習新東西時碰到的不同事物總體上是好的。然而在這種情況下,我建議你現在只是將'cin'和'cout'視爲「魔術」。當然,它們不是魔術,但是它們是使用一些相當先進的技術構建的。現在繼續下去可能會更好,然後在掌握了類,繼承和運算符重載之後再回來。 –

+3

@Muhsin:因爲if表達式是一個布爾值,一個整數或一個指針,因此所有'if'接受。 class std :: istream提供了將輸入流轉換爲布爾值的能力,這是用於評估是否執行if分支或else分支的轉換運算符。 –

6

cin是類型爲istream的(全局)變量,不是函數。

istream類重寫>>運算符以執行輸入並返回對其所稱的對象的引用(cin)。

+0

它不返回對象,它返回對象的引用。不是嗎? – Olympian

+0

@Olympian:不,它是一個實例。 – 2011-07-22 14:38:15

+0

如果cin也是一個變量,那麼我可以寫:x >> cin? –

5

cinstd命名空間中可變。

operator>>返回參考cin,因爲它,你可以寫:cin >> a >> b,而不是cin >> a; cin >> b;

3

因爲表達

cin >> x 

的結果,計算結果爲

cin 

流被讀取。

+0

這意味着我可以調用cin,它仍然會有x的值,直到我覆蓋它爲止? –

+0

不,cin將永遠是istream的一個實例。但變量x將繼續保持其值,因此無論如何都不需要再從流中獲取它。 – Erix

27

注意:在解決C++ 98/03和C++ 11(及更高版本)四年後更新的答案已更新。


std::cinstd::istream的一個實例。該類提供了與這個問題有關的兩個重載。

  • operator >>如果可能的話,將數據從流中讀取到目標變量中。如果流的直接內容不能轉換爲目標變量的類型,則該流將被標記爲無效,並且目標變量保持不變。無論操作是成功還是失敗,返回值都是對流的引用。
  • 或者operator void*()(pre-C++ 11),它將流引用轉換爲void*指針或explicit operator bool()(C++ 11),它將流引用轉換爲布爾值。如果流是有效的,但是空指針(pre-C++ 11)或者false(C + + 11)是非空指針(pre-C++ 11)或者true(C++ 11) +11)如果流無效。

if語句需要一個布爾值,整數或指針作爲要測試的數量。 std::cin >> x的結果是對istream的引用,這不是上述情況。但是,類istream確實具有可用於將istream引用轉換爲if語句中可用內容的那些轉換運算符。它是該語言用於if測試的特定於版本的轉換運算符。由於讀取失敗會將數據流標記爲無效,因此如果讀取不起作用,則if測試將失敗。

的原因更旋繞operator void*轉換構件C++之前圖11是它不是直到C++ 11已經存在的explicit關鍵字被擴展到適用於轉換操作以及構造函數。一個不明確的operator bool()會給程序員提供太多的機會讓自己在腳下自拍。 operator void*()也有問題。 「安全布爾成語」本來就是一個修復,但只是擴展explicit就完成了安全布爾成語的完成,而不必使用大量的SFINAE魔法。

+5

它不使用'運算符bool',而是'operator void *',運算符bool將允許它在算術上下文中使用,而運算符void *防止這種情況,因爲void是不完整的類型。在MSVC編譯器運算符的實現中,如果未設置失敗標誌(不能爲0,因此在布爾上下文中將其評估爲「true」),則返回對象的地址,如果設置了任何標誌,則返回0評估爲布爾值false)。 – lccarrasco

+1

根據http://www.cplusplus.com/reference/ios/ios/operator_bool/,它是C++ 98的'operator void *()'和C++ 11的'operator bool()'。 –

0

據我所知,重載操作符>>返回istream類的對象。這就是爲什麼這裏不是differents

2

上面的答案是信息。這裏我只是給出一個額外的評論。

std::cinistream類的一個對象,並表示標準輸入流(即,鍵盤),其對應於stdin用C

cin >> x將首先從標準輸入流中讀取一個int並將其分配給x。之後返回自己的參考cin。所以函數調用cin >> x的返回值仍然是cin

因此,從的角度看,如果條件,if(cin)if(cin >> x)相互類似。標準IO庫定義一個函數像這樣的流(取決於實現):

explicit operator bool() const; // C++11 

operator void*() const; //C++98, C++2003 

從這兩個聲明,我們知道他們流類型直接或間接(通過void* pinter到bool這是顯而易見的)到bool類型。

在此兩項功能,它們依賴於一些基本IO蒸汽狀態(類字段),以確定是否返回或真或假(爲void*情況下,nullptr與否)。

cin是類istream的一個實例,它繼承了casting-to-bool函數。所以它的作品!

0

1)cinistream的實例,參見http://www.cplusplus.com/reference/iostream/cin/

2)>>運營商的istream將返回其左操作數,在這種情況下,cin,看到http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/。如果沒有從cin中提取字符,此操作員將設置failbit,以防讀取器完成EOF,因此不會再有字符可讀。

3)由於2)中,當條件被讀出操作後進行評價,if (cin >> x)應該像if (cin),參考此鏈接http://www.cplusplus.com/reference/ios/ios/operator_bool/你將看到,這if塊將返回:

  • 如果至少設置了failbitbadbit之一,則爲空指針。其他一些值(用於C++ 98標準)。

  • 如果至少設置了其中一個錯誤標誌,則函數返回false,否則返回true。 (對於C++ 11標準)