-1

I haven't used enums in the past and I'm currently working with a codebase that uses enums and I need to pass them into a function. My understanding is enums are integers, e.g.,

typedef enum {
  toyota = 0,
  honda = 1, 
  volkswagen = 2
} car_brand_t;

If I want to write a function void func that can be called like func(toyota), what should the parameter type be? Can I simply use int like below, or is there something more sophisticated?

void func(int enum_type);
  • 1
    `enum` in an actual type, why don't you say what you mean and just have `void func(car_brand_t);`? – Neil Feb 17 '22 at 14:33
  • @Neil I think I misunderstood `enum`. I thought it worked more like a namespace than an actual type? – westcoaststudent Feb 17 '22 at 14:35
  • In C, all the `enums` get mashed together into one namespace; seems like a good idea to use C++11 scoped enum as in the answer. Enums are limited to a (signed?) integral type, but, unless you have good reason for assigning specific values, it would be more transparent to have the compiler to make the choice. – Neil Feb 17 '22 at 15:09

1 Answers1

5

This is not a good C++ code, it is C code. In C++ you do it like this:

enum car_brand_t
{
  toyota = 0,
  honda = 1, 
  volkswagen = 2
};

void func(car_brand_t value);

With usage: func(toyota)

You can also use more type-safe scoped enum:

enum class car_brand_t
{
  toyota = 0,
  honda = 1, 
  volkswagen = 2
};

void func(car_brand_t value);

With usage: func(car_brand_t::toyota)

APPENDIX

As you asked more specific question, I should extend my answer.

Just want want to confirm that in C++ the enum listings are limited to integers?

Yes, they are integers, signed or unsigned and including bool type. If it is not explicitly defined, compiler is free to choose the type. Specific underlying type can be extracted by a std::underlying_type from <type_traits> header:

enum car_brand_t
{
  toyota = 0,
  honda = 1, 
  volkswagen = 2
};

using the_type = std::underlying_type<car_brand_t>::type; // C++11
using the_type = std::underlying_type_t<car_brand_t>; // C++14

Most popular compilers will choose unsigned int for the example car_brand_t type (as it doesn't contain negative values).

static_assert(std::is_same_v<unsigned, std::underlying_type_t<car_brand_t>>);

If you need,you can specify underlying type explicitly, with the following syntax:

enum car_brand_t : short
{
  toyota = 0,
  honda = 1, 
  volkswagen = 2
};

or

enum class car_brand_t : std::uint8_t
{
  toyota = 0,
  honda = 1, 
  volkswagen = 2
};

This may be very useful, especially when you want to:

  • Have forward declaration of your enum type enum car_brand_t : short;
  • Want to serialize the byte-pattern of some struct containing fixed-size enum:
enum class car_brand_t : std::uint16_t;
struct car_data
{
  car_brand_t brand;
  std::uint16_t manufacture_year;
};

static_assert(
    sizeof(car_data) == 4 &&
    std::has_unique_object_representations_v<car_data> &&
    std::is_trivially_copyable<car_data>
);
Mariusz Jaskółka
  • 4,137
  • 2
  • 21
  • 47