具有C#等属性的C++枚举

C++ enums with attributes like C#

本文关键字:C++ 枚举 属性 具有      更新时间:2023-10-16

我有以下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;

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

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;
}

仅使用枚举是不可能的。然而,我认为你可以通过维护字符串数组/向量/映射或它们的组合来解决这个问题,比如:

enum test
{
    first = 0,
    second, // = 1
    // etc...
};
const char* attributes[] =
{
    "first attribute",
    "second attribute",
};

然后你可以通过检索这个属性

const char* firstattribute = attributes[test::first];