6

I have the following code that I think should compile but doesn't.

#include <cstdint>

typedef uint8_t testtype;

enum testenum : uint8_t {
};

void foo(uint8_t& v) {}

int main() {
    testtype bar;
    foo(bar);

    testenum baz;
    foo(baz);

    return 0;
}

I get the following error:

prog.cpp:15:9: error: invalid initialization of non-const reference of type 'uint8_t& {aka unsigned char&}' from an rvalue of type 'uint8_t {aka unsigned char}'
  foo(baz);

In my mind, this should work because everything is of the same underlying type (uint8_t). A typedef'ed variable can be passed to the foo function, but the enum (which has enum class uint8_t) cannot.

What this means in my project is that I can't pass all of my enums to a single overloaded function -- it looks like I have to create an overload for every possible enum.

Is there an elegant way to get this to compile, or do I have to pass the enum through a second variable that I can pass by reference?

1
  • 4
    testenum can convert to and from uint8_t, but they are not the same. What you are seeing is that the result of the conversion is an rvalue which cannot be bound to non const reference. Commented Jun 24, 2016 at 18:54

1 Answer 1

10

Enums in C++ are more than just applying a name to an integer; we have const int variables for that. Enums conceptually represent an integer which is only supposed to store one of a set of specific values.

Typedefs are aliases; they are identical in every way to the given type. Enums are distinct types. They use their underlying types, and they can be converted to it, but they are not the same type as their underlying types.

As such, a reference to a uint8_t is not the same thing as a reference to an enum, even if that enum uses uint8_t as its underlying type. Converting from a reference-to-enum to a reference-to-underlying-type is therefore an illegal conversion, as well as breaking strict aliasing.

You could pass it by value, since non-class enums are implicitly convertible to their underlying types. And you can pass by const&, since implicit conversion can create a temporary to fill that reference. But you cannot pass an enumeration to a function that takes a non-const reference to an integer.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.