Reputation: 691
I recently learned that I can specify the underlying type of an enumerator in C++11.
I've noticed that I can't for example use an enumerator with an underlying type of uint16_t
as an argument for a uint16_t
parameter. See the following example:
#include <stdint.h>
enum class Apples : uint16_t
{
GRANNY_SMITH = 1
};
class AppleWatcher
{
uint16_t m_apple;
public:
AppleWatcher(const uint16_t apple) : m_apple(apple) {};
};
int main()
{
AppleWatcher(static_cast<uint16_t>(Apples::GRANNY_SMITH)); // This works
AppleWatcher(Apples::GRANNY_SMITH); // Compiler error here
return 0;
}
I still have to explicitly cast to the underlying type to use it in such cases, so what is the purpose of this feature?
Upvotes: 4
Views: 493
Reputation: 38267
This is a type safety feature. Implicit conversions have a long history of associated issues in C++, have a look at Stephen Dewhurst's book "C++ Gotchas" - the longest chapter is that on conversions.
Recall that an enumeration is nothing but a way to bind a constant value to a comprehensible name. This way, there is a finite, documented set of possible values, and by an implicit conversion, you massively extend the domain without giving any notice. Example:
void f(uint16_t arg); // arg can have 65536 different values
enum class Apples : uint16_t { GRANNY_SMITH = 1 }; // one possible value
If this compiles:
f(Apples::GRANNY_SMITH);
you have just given up the restrictiveness without giving notice. Instead,
f(static_cast<uint16_t>(Apples::GRANNY_SMITH));
is clearer and uglier. The clumsy nature of the cast tells you "why do you even do it?", and answering this question shouldn't be too easy. You created the enumeration to refer to possible values by typing out their associated names, right?
Upvotes: 2
Reputation: 21220
According to this documentation page:
There are no implicit conversions from the values of a scoped enumerator to integral types, although static_cast may be used to obtain the numeric value of the enumerator.
So in order to compile your code you need to explicitly cast the value, i.e.:
AppleWatcher(static_cast<uint16_t>(Apples::GRANNY_SMITH));
Upvotes: 0