不允许将强类型枚举用作同一基础类型的参数

strongly typed enums not allowed to be used as arguments of the same underlying type?

本文关键字:类型 参数 强类型 枚举 不允许      更新时间:2023-10-16

请考虑以下代码。我假设通过指定强类型枚举的类型,我将能够使用它传递给相同类型的函数和模板,因为指定的基础类型是相同的;尽管编译器抱怨缺少对该类型的强制转换。在下面的代码中,删除关键字 classTest::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;
}

作用域枚举的全部目的是防止隐式转换为基础类型。您需要强制转换它才能编译代码

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

或者,如果您只关心为枚举指定基础类型,则从其定义中删除 class 关键字,代码将按原样编译。

enum Test : std::size_t {
// ...
};
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
}

现场演示。 请参阅std::underlying_type,了解何时要以编程方式提取类型。