0

I have the following C# Code which I need to convert into C++ code. I have searched for a bit on how to do C++ Enums with Attributes and can not figure it out.

Basically I need a way to represent the following simplified C# Code in C++ which would do enums with attributes.

C# Code:

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                          
        }

Could this be done like this:

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;

and if so how would I call the struct values using the enum?

EST
  • 407
  • 1
  • 7
  • 10
  • "enum with attributes" doesn't mean anything in C++, so you'll have to explain what it is that you want to do. – Pete Becker Aug 04 '16 at 20:48
  • @PeteBecker Thanks for your repsonse. I need to continue using an enum in C++ to represent the basics such that Error = 0 and so forth but for the enum Error I need to place more attributes on it that i can access from it. Basically Error.PSNNumberName = "0 Error" – EST Aug 04 '16 at 20:53

2 Answers2

1

boost::variant and a few visitors should solve it nicely:

#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;
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • I like where you are going but unfortunately I can not move away from the enum because this is in a dll that is called by many other programs. i need to add attributes to the enum while keeping the enum. – EST Aug 04 '16 at 21:23
1

This is not possible with enums alone. However I think you could solve this by maintaining a string array/vector/map or a combination of those to your enum like:

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

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

then you could retrieve this attribute through

const char* firstattribute = attributes[test::first];
Tomas Dittmann
  • 424
  • 7
  • 18
  • I believe something like this would be able to work. I appreciate your answer and help :) – EST Aug 05 '16 at 14:59