2017-02-28 66 views
8

DR 712負責將C++ 11中[basic.def.odr]/2的措辭改爲當前的措辭,[basic.def.odr]2 and 3。但我還是想知道,對於變更的原因,如DR聲明,內容如下:「?用」我只是不明白DR 712

712是一個條件表達式的整數常數操作

在描述類 定義內部初始化的靜態數據成員,9.2.3.2 [class.static.data]段落3表示,

人員應仍然在命名空間範圍來限定,如果它是在程序中使用 .. 。

的「已使用」的定義是在3.2 [basic.def.odr]段落1:

       的物體或非過負荷的函數,其 名稱顯示爲潛在評估
       表達使用,除非它是一個滿足出現在        常量表達式的要求的對象(5.20 [expr.const])和左值到右值轉換(4.1 [conv.lval])
       立即應用。

現在考慮下面的例子:

struct S { 
     static const int a = 1; 
     static const int b = 2; 
}; 
int f(bool x) { 
     return x ? S::a : S::b; 
} 

根據標準的現有措辭,這個例子 要求S::aS::b在命名空間範圍進行定義。 的原因是,根據5.16 [expr.cond]段落4, ,此條件表達式的結果是一個左值,並且將 左值到右值轉換應用於該值,而不是直接應用於該 對象,所以這不符合「立即適用」要求。這是 令人驚訝和不幸,因爲只使用靜態數據成員的值而不是地址。 (這個問題也 適用於問題696的建議的決議)

那麼,如果「立即應用要求不滿足,那麼在條件表達式表達S::aS::b使用(ODR使用的

),所以, struct S的相應靜態成員將會是 而不是需要在名稱空間範圍內定義,但這與DR的說法完全相反。我錯過了什麼?

+1

原來的措辭說,有些東西是odr-used *,除非立即應用* ... l2r,並且由於S :: a和S :: b沒有立即經歷l2r(只有條件表達式是),他們*被使用,因爲「除非」部分不適用。 –

回答

7

我想你再次錯過了used定義的點:

it is used UNLESS ((const) AND (immediately applied)) 

因此,如果「立即應用」是假的,那麼無限是假的,因此它被使用。

+0

是的,你是對的。對於不使用的物體,必須滿足這兩個條件。 – Ayrosa

2

的物體或非過載功能,其名稱爲潛在評估表達使用,除非出現[...]

那麼,S::aS::b內出現在f潛在評估表達。

因此,它們被使用,除非有以下例外情況之一。

它是一個滿足出現在常量表達式(5.20 [expr.const])中的要求並且左值到右值轉換(4.1 [conv.lval])爲立即申請。

那麼,它是一個滿足出現在常量表達式中的對象。所以它通過了這個測試。

但是左值到右值的轉換沒有立即應用。

所以它沒有通過測試。

由於整個部分在「除非」之下,故障意味着前面的情況適用;該對象被視爲「已使用」。