【问题标题】:C++ enums with attributes like C#具有 C# 等属性的 C++ 枚举
【发布时间】:2016-08-04 20:27:50
【问题描述】:

我有以下 C# 代码,我需要将其转换为 C++ 代码。我已经搜索了一些关于如何使用属性进行 C++ 枚举的内容,但无法弄清楚。

基本上,我需要一种方法来用 C++ 表示以下简化的 C# 代码,该代码将使用属性进行枚举。

C#代码:

public class PSMNameAttribute : Attribute
        {
            public string PSMName;
            public PSMNameAttribute(string _PSMName) { PSMName = _PSMName; }
        }

public class PSMNumberAttribute : Attribute
        {
            public string PSMNumber;
            public PSMNumberAttribute(string _PSMNumber) { PSMNumber = _PSMNumber; }
        }

public class PSMNumberNameAttribute : Attribute
        {
            public string PSMNumberName;
            public PSMNumberNameAttribute(string _PSMNumberName) { PSMNumberName = _PSMNumberName; }
        }


public enum ShippingMethodsTypes
        {
            [PSMName("ErrorScriptMed")]
            [PSMNumber("-5")]
            [PSMNumberName("-5 ErrorScriptMed")]
            ErrorScriptMed = -5                 
            ,
            [PSMName("SpecialHandling")]
            [PSMNumber("-1")]
            [PSMNumberName("-1 SpecialHandling")]
            SpecialHandling = -1                
            ,
            [PSMName("Error")]
            [PSMNumber("0")]
            [PSMNumberName("0 Error")]
            Error = 0                          
        }

可以这样做吗:

enum Category{ 
    unknown = -1, meat, poultry, seafood, dairy, vegetable,fruit, grain, sweet
};

typedef struct {
    float calories; // calories
    float carbonhydrates; // grams
    float fat; // grams
    float cholesterol; // grams
    float sodium; // grams
    float protein; // grams
    Category category ;
}Food;

如果是这样,我将如何使用枚举调用结构值?

【问题讨论】:

  • “带属性的枚举”在 C++ 中没有任何意义,所以你必须解释你想要做什么。
  • @PeteBecker 感谢您的回复。我需要继续在 C++ 中使用枚举来表示基本知识,例如 Error = 0 等等,但是对于枚举错误,我需要在其上放置更多我可以从中访问的属性。基本上 Error.PSNNumberName = "0 错误"

标签: c++ enums attributes enumeration


【解决方案1】:

boost::variant 和一些访客应该很好地解决它:

#include <boost/variant.hpp>
#include <iostream>

struct get_number : boost::static_visitor<int> {
  template<class Method> int operator()(const Method& m) const { return number(m); }
};

struct get_name : boost::static_visitor<std::string> {
  template<class Method> const std::string operator()(const Method& m) const { return name(m); }
};

struct ShippingMethodMed {};
static constexpr int number(ShippingMethodMed) { return -5; }
static std::string name(ShippingMethodMed) { return "ErrorScriptMedMed"; }

struct ShippingMethodSpecialHandling { };
static constexpr int number(ShippingMethodSpecialHandling) { return -10; }
static std::string name(ShippingMethodSpecialHandling) { return "SpecialHandling"; }

struct ShippingMethodError {};
static constexpr int number(ShippingMethodError) { return 0; }
static std::string name(ShippingMethodError) { return "Error"; }

using ShippingMethod = boost::variant<ShippingMethodMed, ShippingMethodSpecialHandling, ShippingMethodError>;

int number(ShippingMethod const& sm) {
  return boost::apply_visitor(get_number(), sm);
}

std::string name(ShippingMethod const& sm) {
  return boost::apply_visitor(get_name(), sm);
}

std::string number_name(ShippingMethod const& sm) {
  return std::to_string(number(sm)) + " " + name(sm);
}


int main()
{
  ShippingMethod m = ShippingMethodError();

  std::cout << number(m) << std::endl;
  std::cout << name(m) << std::endl;
  std::cout << number_name(m) << std::endl;

  m = ShippingMethodSpecialHandling();

  std::cout << number(m) << std::endl;
  std::cout << name(m) << std::endl;
  std::cout << number_name(m) << std::endl;
}

【讨论】:

  • 我喜欢你要去的地方,但不幸的是我不能离开枚举,因为它在一个被许多其他程序调用的 dll 中。我需要在保留枚举的同时向枚举添加属性。
【解决方案2】:

仅使用枚举是不可能的。 但是我认为您可以通过维护一个字符串数组/向量/映射或将它们组合到您的枚举中来解决这个问题,例如:

enum test
{
    first = 0,
    second, // = 1
    // etc...
};

const char* attributes[] =
{
    "first attribute",
    "second attribute",
};

那么你可以通过

检索这个属性
const char* firstattribute = attributes[test::first];

【讨论】:

  • 我相信这样的事情会奏效。感谢您的回答和帮助:)
猜你喜欢
  • 2015-04-14
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多