【问题标题】:strongly typed enums not allowed to be used as arguments of the same underlying type?不允许将强类型枚举用作相同基础类型的参数?
【发布时间】:2016-01-20 16:46:27
【问题描述】:

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

【问题讨论】:

    标签: c++ c++11 enums strongly-typed-enum


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 是的,这基本上就是我最终要做的。感谢您的解释
    【解决方案2】:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 2020-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多