[英]Variable definition to boolean value conversion in C++
我發現以下代碼在 C++98 及更高版本中有效:
if (int x = 7) { // int x; if (x = 7) makes sense
std::cout << x << '\n'; // 7 is printed
}
問題:控制變量定義到布爾表達式的轉換的規則是什么?
如果它像下面那樣,那么 b/c if 條件是一個賦值表達式,它會計算為一個整數:
int x;
if (x = 7) {
std::cout << x << '\n';
}
賦值表達式的結果是賦值目標,在本例中為x
。 由於bool(7)
為真,條件為真。
此功能的一個常見用法更有用,如下所示:
if (auto* x = get_some_pointer())
// use x, which is known to be not null
變量在哪里聲明與它無關。 按照你的例子,這會做同樣的事情:
int x;
if (x = 7)
// ...
管理這部分語法的規則在[stmt.pre]
健康)狀況:\n 表達\n 屬性說明符-seq opt decl-specifier-seq聲明符大括號或等號初始化器4不是表達式的條件是聲明 ([dcl.dcl])。 聲明符不應指定函數或數組。 decl-specifier-seq 不應定義類或枚舉。 如果 auto 類型說明符出現在 decl-specifier-seq 中,則聲明的標識符的類型是從初始化程序中推導出來的,如 [dcl.spec.auto] 中所述。
6在 switch 語句以外的語句中作為初始化聲明的條件的值是根據上下文轉換為 bool 的聲明變量的值。 如果該轉換格式錯誤,則程序格式錯誤。 在 switch 語句中作為初始化聲明的條件的值是聲明變量的值,如果它具有整數或枚舉類型,或者該變量隱式轉換為整數或枚舉類型,否則。 作為表達式的條件的值是表達式的值,對於 switch 以外的語句,上下文轉換為 bool; 如果該轉換格式錯誤,則程序格式錯誤。 條件的值將簡單地稱為“條件”,其中用法是明確的。
7如果條件可以在語法上解析為表達式或塊范圍名稱的聲明,則將其解釋為聲明。
8在條件的 decl-specifier-seq 中,每個 decl-specifier 要么是類型說明符,要么是
constexpr
。
上述文本中的condition
是出現在if (condition)
, while (condition)
和switch (condition)
的語法產生式中的語法元素。 [stmt.stmt] 中大多數其他提到的condition
在轉換為布爾值或整數值(在開關中)后處理其值。 而基於價值的行為正是人們所期望的。
在別處提到的唯一另一件值得注意的事情是聲明關於其聲明區域的行為。 例如,在 if 語句中
if(auto handle = getHandle())
handle->foo();
else
handle->bar();
該名稱在兩個分支中均可用。 但這在[basic.scope.block] 中提到
3在 init-statement、for-range-declaration 以及 if、while、for 和 switch 語句的條件中聲明的名稱是 if、while、for 或 switch 語句(包括受控語句)的局部名稱,並且不應在該語句的后續條件中或在受控語句的最外層塊(或對於 if 語句,任何最外層塊)中重新聲明。 [ 例子:
if (int x = f()) { int x; // error: redeclaration of x } else { int x; // error: redeclaration of x }
— 結束示例 ]
與 C 一樣,C++ 布爾值被視為值為 0 或 1 的整數。當從其他值轉換時,如果值為 0,它會將布爾值解析為 false,如果值為零,則每隔一個數字變為 true。
這可以輕松檢查指針(也可以解釋為數字),其中值為 0 的指針是空指針。
任何賦值語句的結果都是賦值后左操作數的值。
零值(對於整數、浮點和無作用域枚舉)以及空指針和指向成員的空指針值變為假。 所有其他值都變為真。
所以這里 int x 的值為 7 變為真。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.