Of course this is all doable in C
That doesn't mean that the minds behind C++ automatically consider it a desired behavior. Nor should they have such an attitude. C++ follows its own philosophy with regard to types. This is not the only aspect where a conscious decision was made to be more strongly typed than C. This valid C snippet is invalid in C++
void *vptr = NULL;
int *iptr = vptr; // No implicit conversion from void* to T* in C++
How is it expected that I can assign an enum value to an int but not the other way in C++?
It's the behavior because one side of the conversion is less error prone. Allowing an enumerator to become an integer isn't likely to break any assumptions the programmer has about an integer value.
An enumeration is a new type. Some of the enmueration's values are named. And for most cases of using an enumeration, we really do want to restrict ourselves to those named constants only.
Even if an enumeration can hold the integer value, it doesn't mean that value is one of the named constants. And that can easily violate the assumptions code has about its input.
// Precondition: e is one of the name values of Enum, under pain of UB
void frombulate_the_cpu(Enum e);
This function documents its precondition. A violation of the precondition can cause dire problems, that's what UB usually is. If an implicit conversion was possible everywhere in the program, it'd be that more likely that we violate the precondition unintentionally.
C++ is geared to catch problems at compile time whenever it can. And this is deemed problematic.
If a programmer needs to convert an integer an enumeration, they can still do it with a cast. Casts stand out in code-bases. They require a conscious decision to override a compiler's checks. And it's a good thing, because when something potentially unsafe is done, it should be with full awareness.