2012-11-08 78 views
2

無條件需要強類型枚舉中顯式範圍解析的基本原理是什麼?強類型枚舉中範圍解析的基本原理

N2347解釋了與舊式枚舉不同的地方,這些舊式枚舉不存在隱式轉換,指定存儲類型的能力以及在周圍範圍內不注入名稱(如在C++ 03中,它具有作爲C)。

換句話說,寫作enum E1 { a, b, c};如在C++ 03類似於編寫

const int a = 1; const int b = 2; const int c = 3; 

enum E1 class { a, b, c};如在C++ 11被更類似於像

namespace E1 { const int a = 1; const int b = 2; const int c = 3; } 

(而不用引入一個名稱空間,並在任何情況下定義枚舉類型)。

現在,我一般不明白的地方出現混淆,假設一個有類似於下面的示例代碼(這不會編譯):

enum class E1 { a, b, c }; 
enum class E2 { a, b, c }; // allowed now 

void foo(E1 e) { ... } 
void bar(E2 e) { ... } 
void baz(int e) { ... } 

foo(a); // not ambigious: E1 expected, nothing but E1::a possible 
bar(a); // not ambigious: E2 expected, nothing but E2::a possible 
baz(a); // not ambigious: illegal - no name `a` in global scope 

E1 x = a; // not ambigious: E1 expected, nothing but E1::a possible 

我歡迎(可選)明確範圍分辨率在某些情況下指出發生了什麼,但我不明白爲什麼C++ 11需要明確的作用域解析,即使沒有其他方式可能解釋代碼。

在我看來這是合理的,例如void foo(E1 e);的含義更像void foo(using enum E1; E1 e);(我的語法當然是完全錯誤的,但你明白了)。

以的ColorAlert,這也是在N2347「經典」的例子,一個具有紅色警報,並且紅色,其可以是不同的數值常量,太。如果沒有強類型保證,可以想象當人們真的想要例如使用警告數字常量時,結果是最終的。在顯示器上設置紅色。或者,使用整數轉換和寬鬆的函數聲明,可以想象有人最終會使用類似yellow|red的東西來獲取橙色。

這一切都不可能,所以我們究竟是在防範什麼呢?

回答

5

foo(a); //不含糊:E1預期,只有E1 ::可能

必須知道表達式的類型。而且由於使用a作爲獨立表達是不明確的,因此在任何地方使用a都是不明確的。

您不希望表達式根據其使用的上下文來更改它們的含義。1 + 1始終表示相同的事物。如果你使用相同的t1 + t總是意味着相同的東西。同樣,無論在何處使用,a應該始終表示相同的內容。

C++中唯一允許根據使用它的上下文來推導源類型的方法是統一初始化。並且該標準明確指出「braced-init-list」是而不是的表達式。a是一個表達式,所以它遵循表達式規則。

+0

這很有道理,謝謝。 – Damon