2016-08-04 4 views
0

У меня есть следующий код C#, который мне нужно преобразовать в код C++. Я немного искал, как делать C++ Enums с атрибутами и не могу понять это.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; 

, и если да, то как бы я называю значения STRUCT с помощью перечисления?

+0

«перечисление с атрибуты "ничего не значит в C++, поэтому вам придется объяснить, что именно вы хотите сделать. –

+0

@PeteBecker Спасибо за ваш ответ. Мне нужно продолжить использование перечисления в C++ для представления основ, таких как Error = 0 и т. Д., Но для ошибки перечисления мне нужно разместить на нем больше атрибутов, из которых я могу получить доступ. В основном Error.PSNNumberName = "0 Error" – bing281

ответ

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

Мне нравится, куда вы идете, но, к сожалению, я не могу отойти от перечисления, потому что это в DLL, которая вызывается многими другими программами. Мне нужно добавить атрибуты в перечисление, сохраняя перечисление. – bing281

1

Это не возможно с только перечислений. Однако я думаю, что вы могли бы решить эту проблему, поддерживая строковый массив/вектор/карту или комбинацию тех, к вашему перечислимого типа:

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

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

, то вы могли бы получить этот атрибут через

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

Я верю, что что-то подобное сможет работать. Я ценю ваш ответ и помогаю :) – bing281

 Смежные вопросы

  • Нет связанных вопросов^_^