I have a small, in-progress, project specifically chosen to let me explore and learn C++. In this project, I had declared an enum in a global.h file, which consisted of, mostly, static const ints. global.h was included in a number of other compilation units and everything worked.
I decided to update the enum to an enum class. I missed some of the consequences (no implicit conversion to int, for example) but I worked through those. I even added an operator++() overload to the enum class, which I inserted in the global.h file.
I got "multiple declarations of operator++()" linker errors but I figured out why: It was finding the definition in each of the .obj files. Adding "inline" to the definition solved the problem.
What I don't understand is why?
I suppose I could have created a global.cpp and moved the operator++() definition there but that seemed to defeat the purpose of setting the global values aside in a .h.
The operator++() is just a function like any other, and if a function definition appears in multiple translation units then it needs to be inline, otherwise the linker doesn't know how to resolve the multiple definitions issue.
By the way, you can make your implementation shorter:
If the input has a value > kWxData::END_OF_ENUM the program has undefined behavior anyway. The default case does make sense in case new values get added to the enum, to let the maintainer know to update the implementation, however the modulo operation sidesteps that issue entirely and doesn't need updating.
For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type.
An "enum class" always has a fixed underlying type that defaults to int. That means you could legally, as far as the C++ standard is concerned, store any valid int value in a kWxData enum.
Note that this implementation is for prefix increment (eg ++data). It won't work for postfix increment (eg data++) which needs to be implemented separately. eg.
The keyword "inline" is misleading in this regard.
Is it because inline drops the code in wherever it occurs and no operator++ is actually called?
Not necessarily. The C++ keyword "inline" doesn't actually force inlining, it just means you are allowed to have multiple definitions of the same function.
So now, A.cpp can define the operator++ function, and B.cpp can also define the same function (either from copy-paste* or #include).
*But under no circumstances would I suggest actually copy-pasting the non-static inline function into multiple files because if those two inline functions diverge, you get undefined behavior because the compiler is allowed to assume both functions have the same address.