3

Suppose I have the following code in another library that I can't change:

typedef enum {
    p0  = 0,
    p1  = 1,
    p2  = 2,
    p3  = 3,
    p4  = 4,
    p5  = 5,
    p6  = 6,
    ...
} PinName;

I want to add some extra aliases like this (not using const PinName PIN_...):

enum class : PinName {
    PIN_SD_MOSI = p0,
    PIN_SD_MISO = p4,
    PIN_SD_SCK = p2,
    PIN_SD_CSN = p6,
};

But it doesn't work. I get the following error:

error: underlying type 'PinName' of '<anonymous enum class>' must be an integral type
  enum class : PinName {
               ^

I also tried using enum class : int { but then the aliases are never in scope - I suspect I have to use plain enum instead. enum : int compiles, but then you can't pass any of the aliases to functions that take PinName. You get this error:

error: no matching function for call to 'foo(<anonymous enum>, <anonymous enum>)'
 foo(PIN_SD_MISO, PIN_SD_MOSI);
     ^

(Candidate is foo(PinName, PinName).)

Does anyone have any idea of a nice solution before I give up and use const PinName PIN_SD_MISO = p2;?

erip
  • 16,374
  • 11
  • 66
  • 121
Timmmm
  • 88,195
  • 71
  • 364
  • 509

3 Answers3

0

Kind of hacky but this is what I came up with if dealing with scoped enums:

enum class OriginalType {
   FOO,  // 0
   BAR   // 1
   END   // 2
};

enum class ExtendOriginalType : std::underlying_type_t<OriginalType> {
   EXTENDED_FOO = static_cast<std::underlying_type_t<OriginalType>>
                                           (OriginalType::END), // 2
   EXTENDED_BAR  // 3
};

and then use like:

OriginalType myOriginalType = (OriginalType)ExtendOriginalType::EXTENDED_BAR;

from Base enum class inheritance

jsadler
  • 109
  • 6
0

I will be shot down for this, but why not just use macros?

#define PIN_SD_MOSI  p0
#define PIN_SD_MISO  p4
#define PIN_SD_SCK   p2
#define PIN_SD_CSN   p6
TonyK
  • 16,761
  • 4
  • 37
  • 72
0

I don't see any other "nice" solution besides a set of constants:

constexpr auto PIN_SD_MOSI = p0;
constexpr auto PIN_SD_MISO = p4,
constexpr auto PIN_SD_SCK = p2;
constexpr auto PIN_SD_CSN = p6;

You could also use another unscoped enum:

enum PinName2 {
    PIN_SD_MOSI = p0,
    PIN_SD_MISO = p4,
    PIN_SD_SCK = p2,
    PIN_SD_CSN = p6,
};

The "problem" with scoped enums is that they're their own type, and they don't implicit convert to the underlying type.

Vivick
  • 3,434
  • 2
  • 12
  • 25