2016-01-20 75 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