簡體   English   中英

C++ 在條件中依賴隱式轉換為 bool 嗎?

[英]C++ rely on implicit conversion to bool in conditions?

我在編碼標准表中發現了以下規則:

不要依賴隱式轉換為條件中的 bool。

if (ptr) // 錯誤

if (ptr != NULL) // 好的

這個規則有多合理/有用?

編譯后的代碼有多少重載?

在最嚴格的意義上,您可以依靠隱式轉換為 bool。 與 C 的向后兼容性需要它。

因此,它成為代碼可讀性的問題。 代碼標准的目的通常是強制代碼風格保持一致,無論您是否同意這種風格。 如果您正在查看其他人的標准並想知道是否應該將其納入您自己的標准,請繼續進行辯論 - 但如果這是您公司的長期規則,請學會接受它。

如果您想使用隱式轉換為bool ,例如std::istream ,那么該規則會使您陷入困境。 此代碼一次從文件中讀取一個單詞,直到達到 EOF:

std::ifstream file("foo.txt");
std::string word;

while (file >> word)
{
    // do stuff
}

流提取運算符返回對文件流的引用,該引用隱式轉換為bool以指示流是否仍處於良好狀態。 當您到達文件末尾時,測試失敗。 您的編碼標准禁止您使用此通用結構。

對於指針類型,這沒什么大不了的。 編譯器可能會為隱式轉換為bool和針對NULL的顯式測試生成大致相同的代碼。 在這一點上,這是一個品味問題 - 從絕對意義上講,沒有一個是“更好的”。 編碼標准只是試圖強制執行一致的風格。

考慮到這一點,在處理內置類型(指針、整數等)時,您絕對應該遵循編碼標准。 如果您遇到與上述類似的情況,並且類具有合法的bool轉換,我會向您的隊友提出這個問題。

在大多數情況下,這是不可怕的,但如果你恰好鍵入你的意思也可以是更具可讀性。

我想為這個問題添加一個歷史觀點。

ANSI C (又名 C89/C90)是C的第一個正式規范。與K&R C 一起,您可能會注意到一些特殊的東西——沒有布爾值的概念。 控制流語句對表達式進行操作,它們的流是根據表達式的計算結果是否為0來定義的。 缺少布爾類型是 C 最大的疏忽之一。直到 C99,C 才獲得了_Bool類型,並在stdbool.hbooltruefalse定義了宏(注意它們仍然是整數)。 同樣,C++ 最初也沒有布爾類型,在C++98 中使用bool獲得它。

這就是為什么有到布爾值的隱式轉換。 在我看來,繼續依賴它是糟糕的設計——添加布爾值是有原因的。 true應始終等於true ,並且將所有非零值隱式轉換為 true 是不令人滿意的。

NULL也只是一個等於 0 的宏,所以具體來說,對於 C++11 中的指針,您應該使用nullptr來確定指針是否為空。

if(ptr != nullptr)
{
    // Do something with ptr.
}

這根本不會影響編譯后的代碼。

至於它有多有用 - 它肯定會幫助來自 Java/C# 等語言的人的理解。 這將使您更明確地檢查您要檢查的內容。 如果您開始將 int 與 NULL 進行比較,它會發出警告(從而表明您對相關變量的類型感到模糊)。 我個人更喜歡第一種形式,但這並不是一個完全不合理的要求。

有時我認為這條規則可能會被打破,例如在處理返回int而不是bool標准庫時(為了與 C8​​9 兼容)。

但是,此規則通常會導致代碼更易於理解。 它甚至在像 C# 這樣的語言中被強制執行,並且在那里並沒有抱怨太多,所以除了必須習慣它之外,遵循這個規則沒有什么大的缺點。

我非常不喜歡這個規則。 在 C++ 中,對於指針類型(當然對於布爾類型)使用到 bool 的隱式轉換是慣用的。 IMO,它更容易閱讀

bool conditionMet = false;

while (!conditionMet) // read as "while condition is not met"
{
    /* do something */
}

不是讀這個:

bool conditionMet = false;

while (conditionMet == false) // read as "while conditionMet is false"
{
    /* do something */
}

指針也是一樣。 此外,通過引入不必要的比較,您又引入了另一個錯誤輸入的機會,並以賦值而不是比較結束,這當然會產生不想要的結果。 如果您使用整數作為布爾值,就像使用舊的 C 代碼一樣,我認為您還應該使用隱式轉換為布爾值。

增加零收益的規則是您可以有利地刪除的規則。

這是一個令人印象深刻的愚蠢規則。

if (ptr != NULL) // ok

那為什么不呢

 if ((ptr != NULL)==true) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM