简体   繁体   English

如何确定某个值是否在C ++中的枚举类型中定义?

[英]How to identify if the certain value is defined in an enum type in C++?

I need to check if some values are defined in the enum type or not at runtime in C++. 我需要检查在C ++中在运行时是否在枚举类型中定义了某些值。 The requirement could be easily accomplished by C# (refer the following code). 该要求可以通过C#轻松实现(请参阅以下代码)。 But C++ doesn't have type information at runtime (as far as I know). 但是C ++在运行时没有类型信息(据我所知)。 Is there a way to workaround? 有没有解决方法?

PS: In my project, the enum type defines hundreds of values, so I don't want to duplicate the values in source code (eg create a map and push all the valid values into it) that implements the logic which increases the complexity of maintainability. 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
        }
    }
}

What you are looking for it's called reflection , C++ doesn't provide this feature, however there are several articles about this . 您正在寻找的被称为反射 ,C ++没有提供此功能,但是有关此的文章很多

Also the new C++11 standard introduces something new about enums making them much more type safe and not just a random variable with a value. 同样,新的C ++ 11标准引入了一些有关枚举的新内容,使它们更具有类型安全性,而不仅仅是具有值的随机变量。

There is workaround, but its verbose as it comes in the form of boost::fusion . 有解决方法,但是它以boost :: fusion的形式出现时比较冗长。 This library derives its name from its purpose of being a hybrid of the pure compile-time template metaprogramming library boost::mpl and the run-time Standard Template Library . 该库的名称源于其作为纯编译时模板元编程库boost :: mpl和运行时标准模板库的混合体的目的

boost::fusion allows a vector or map to be initialized and utilized at compile time and also used at runtime as well. boost :: fusion允许矢量或映射在编译时进行初始化和使用,也可以在运行时使用。

C++ does not provide what you want. C ++不提供您想要的。

Most "proper" solution is to re-design the whole thing, and not use C++ enum like this. 最“合适”的解决方案是重新设计整个过程,而不是像这样使用C ++枚举。 It is not same as C# enum, they are different enough that you should not think of them as a same thing, any more than you think union and enum are same thing. 它与C#枚举不同,它们之间的差异足够大,以至于您不应将它们视为同一事物,甚至比您认为union和enum是同一事物还要多。 Clear your mind of C# solution, design C++ solution. 清除您的C#解决方案,设计C ++解决方案。

Easiest, especially if enum values do not change often (and if they do, why are they a hard-coded enum?), is to just "bite the bullet" and create a set or a map with valid values, and when you want to know if some number is defined as enum, test if it is in set, or if you also want the name, then use map so you can include both value as int and name as string. 最简单,特别是如果枚举值不经常更改(如果改变的话,为什么它们是硬编码的枚举?),则只是“硬着头皮”并创建具有有效值的集合或映射,以及何时需要要知道某个数字是否定义为枚举,请测试它是否已设置为枚举,或者是否还需要名称,请使用map,以便可以同时将value和int都包括在内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM