2016-01-20 93 views
1

請考慮以下代碼。我假設通過強類型枚舉的類型指定我可以使用它傳遞給相同類型的函數和模板,因爲指定的基礎類型是相同的;儘管編譯器會抱怨缺少類型轉換。在下面的代碼中刪除關鍵字class和枚舉Test::TOTAL_ITEMS返回TOTAL_ITEMS的說明符將工作。我知道他們不希望對強類型枚舉進行任何類型轉換,但是當基礎類型與預期會被函數或模板接收的類型相同時,我希望編譯器不會抱怨這一點,也不會強制一個特定的演員。思考?強類型枚舉不允許用作相同基礎類型的參數?

#include <iostream> 
#include <cstdint> 

template <typename T, std::size_t N = 10> 
class Y { 
public: 
    Y() : z_() { 
    } 
    ~Y() = default; 

private: 
    T z_[N]; 
}; 

class X { 
public: 
    enum class Test : std::size_t { 
     ITEM1 = 0, 
     ITEM2, 
     TOTAL_ITEMS, 
    }; 

private: 
    Y<int, Test::TOTAL_ITEMS> collection; 
}; 

int main() { 
    X xx; 
} 

回答

3

範圍枚舉的全部用途是爲了防止對基礎類型的隱式轉換。你需要投它讓你的代碼編譯

#include <type_traits> 
Y<int, static_cast<std::underlying_type<Test>::type>(Test::TOTAL_ITEMS)> collection; 

或者,如果你關心的是指定爲您的枚舉基礎類型,然後從它的定義刪除class關鍵字,你的代碼將編譯原樣。

enum Test : std::size_t { 
// ... 
}; 
+0

是的,這基本上是我最終做的。感謝您的解釋 – bjackfly

0

enum class的目的是保持它的實例從隱含鑄造一些其他類型。這就是刪除class編譯的原因:常規enum實例隱式轉換爲其基礎類型可以執行的任何操作。

當你想要一個enum class轉換成一些其他類型的,你必須這樣做明確

enum class Foo : int { FEE, FYE, FOE, FUM }; 
void f(Foo x) {}; 
void g(int x) {}; 

int main() 
{ 
    f(Foo::FEE);     // Okay: correct type 
    //f(0);      // Error: no implicit conversion 
    f(static_cast<Foo>(0));  // Okay: explicitly converted 
    //g(Foo::FYE);     // Error: no implicit conversion 
    g(1);       // Okay: correct type 
    g(static_cast<int>(Foo::FYE)); // Okay: explicitly converted 
} 

Live demo。當您想要以編程方式提取類型時,請參閱std::underlying_type