2013-07-24 51 views
4

我做了一個枚舉一個小的測試,這裏就是我:C++類型爲char的枚舉,被編譯器忽略或意外的行爲?

enum anyoldname : char 
{ 
    aa = 'a', ab = 'b', ac = 'c', ad = 'd' 
}; 

int main() 
{ 

    anyoldname i_have_an_enum_here = aa; // Would expect i_have_an_enum_here to be of type char? 

    std::cout << i_have_an_enum_here << std::endl; 

    return 0; 
} 

輸出爲:98,除非我投明確燒焦像這樣:

std::cout << (char)i_have_an_enum_here; 

或更改anyoldnamechar

爲什麼打印值98而不是b

順便提一句sizeof()返回1,即; 1個字節,一個char

+0

對不起,它應該是'aa','aa =='a''爲真 – user3728501

回答

3

沒有鑄造中,爲了std::ostream適當的成員函數的編譯器首先搜索,它找到一個 - 的一項所述的用於int。因此,它會將您的1字節數anyoldname隱式轉換爲int並調用成員函數。

編譯使用g ++ 4.8.1程序,用於ostream::operator<<兩種定義都看出:

 U std::ostream::operator<<(std::ostream& (*)(std::ostream&))@@GLIBCXX_3.4 
    U std::ostream::operator<<(int)@@GLIBCXX_3.4 

第一個是爲endl,第二個是用於您的枚舉。

隨着明確投爲char,編譯器能夠找到一個完美的匹配,在全球std::operator<<函數,它接受一個ostreamchar作爲輸入。然後它使用此函數而不是執行隱式強制轉換(再次轉換爲int)以調用ostream成員函數。

兩個符號變爲:

 U std::ostream::operator<<(std::ostream& (*)(std::ostream&))@@GLIBCXX_3.4 
    U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char) 

和你的價值觀打印爲字符,而不是他們的十進制值。

1

如果你要讀的C++標準(我只有C++ 11現在)第7.2節第5段:

每個枚舉定義了一個類型,它是從所有其他類型不同。每個枚舉也有一個 基礎類型。基礎類型可以使用enum-base明確指定;如果沒有明確指定,...

特別是這意味着你的anyoldname實際上是一個獨立的類型其大小一樣char(因爲它的基礎類型在聲明中明確規定)。所以,沒有理由被隱式轉換爲char

+1

+1用於引用標準。 – BrainSteel

+1

這是真的,但編譯器必須隱式地將枚舉類型轉換爲* something *。這就是爲什麼他得到了一個打印輸出,而不是一個抱怨新類型缺少'operator <<'的編譯器錯誤。 – Corey