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?
Can we pass enum by reference? If they represent similar things, why not create a data structure which contains all the required data and will then easily be passed by reference. That's a valid point.
enum class holds an integral value just like a regular enum so you can safely pass it by value without any overhead. Notice that compiler may sometimes optimize pass by reference as well by replacing it with pass by value. But passing by reference may result in some overhead when such an optimization is not applied.
In Java you cannot pass any parameters by reference. The only workaround I can think of would be to create a wrapper class, and wrap an enum. Now, reference will contain a different value for your enum; essentially mimicking pass-by-reference.
2.2. Inheritance Is Not Allowed for Enums.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With