【问题标题】:How to identify if the certain value is defined in an enum type in C++?如何识别某个值是否在 C++ 的枚举类型中定义?
【发布时间】:2012-11-13 06:44:53
【问题描述】:

我需要在 C++ 运行时检查枚举类型中是否定义了某些值。该要求可以通过 C# 轻松完成(参考以下代码)。但是 C++ 在运行时没有类型信息(据我所知)。 有办法解决吗?

PS:在我的项目中,枚举类型定义了数百个值,因此我不想在源代码中复制这些值(例如,创建一个映射并将所有有效值推入其中)实现增加的逻辑可维护性的复杂性。

enum BoFormObjectEnum
{
    fo_Items = 4,
    fo_SalesEmployee = 53,
    fo_TransactionTemplates = 55,
    fo_JournalPosting = 30,
    fo_CheckForPayment = 57,
    fo_PaymentTermsTypes = 40,
    ...
}

class Program
{
    static void Main(string[] args)
    {
        var array = Enumerable.Range(1, 60);
        foreach (var item in array)
        {
            if (Enum.IsDefined(typeof(BoFormObjectEnum), item))
                // do some logic
            else
                // do some other logic
        }
    }
}

【问题讨论】:

  • “这增加了可维护性的复杂性”——在运行时这样做实际上会增加调试和维护的成本
  • 你能给出一个小的 C++ 示例代码,你打算在哪里使用这个枚举?
  • 为什么枚举没有按顺序写?
  • 简短回答:不。更长的答案:想要/使用它表明您的设计可能不适合 C++(而且我几乎会认为这只是一个糟糕的设计,显然很常见,以至于 C# 有一个创可贴帮助人们做出如此糟糕的设计)。
  • 另一个使用包装类的好理由,或者这个 Boost 非官方扩展枚举:github.com/boost-vault/Miscellaneous(文件名为 enum_rev4.6.zip)

标签: c# c++ enums


【解决方案1】:

C++ 没有提供你想要的。

大多数“正确”的解决方案是重新设计整个事物,而不是像这样使用 C++ 枚举。它与 C# enum 不同,它们的不同之处足以让您不应该将它们视为同一事物,就像您认为 union 和 enum 是同一事物一样。清除 C# 方案的头脑,设计 C++ 方案。

最简单的方法,特别是如果枚举值不经常更改(如果更改,为什么它们是硬编码的枚举?),就是“咬紧牙关”并创建具有有效值的集合或映射,并且当您想知道某个数字是否定义为枚举时,请测试它是否在集合中,或者您是否还想要名称,然后使用 map 这样您就可以将值包含为 int 并将名称包含为字符串。

【讨论】:

  • 最后,我重新设计了整个东西。枚举在解决方案中消失了。非常感谢!
【解决方案2】:

你要找的是reflection,C++不提供这个功能,但是有several articles about this

此外,新的 C++11 标准引入了something new about enums,使它们的类型更加安全,而不仅仅是带有值的随机变量。

【讨论】:

    【解决方案3】:

    有一种解决方法,但它以boost::fusion 的形式出现,因此比较冗长。这个库得名于它的目的是混合纯编译时模板元编程库boost::mpl 和运行时Standard Template Library

    boost::fusion 允许在编译时初始化和使用向量或映射,也可以在运行时使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 2016-09-08
      • 1970-01-01
      相关资源
      最近更新 更多