I have the following methods (broadly speaking) in my bitstream class:
class BitStream
{
void StoreBits( unsigned int data, unsigned int numBits );
public:
template<typename T>
void WriteType( T value ) { StoreBits( value, sizeof(T) * 8 ) );
template<>
void WriteType( float value ) { StoreBits( *(unsigned int*)&value, sizeof(float) * 8 ) );
};
Someone has thrown a strongly type enum class at WriteType, and obviously the enum does not automatically convert to an unsigned integer.
What can I do to write a specialization that handles all enumeration cases using the same function naming?
This is a trivialization of the problem - I have enum class instances being thrown at a number of other BitStream member methods that I have to handle, such as ReadType, StreamType (read or write), SmallestRangeWrite<Min,Max>() etc.
I have C++17 support available. I know there is std::is_enum, but how can I specialize on that here, especially at compile time?
Could I somehow write:
template<typename T>inline void BitStream::WriteType( T value )
{
if (type_is_enum())
StoreEnum<T>(value)
else
StoreBits( value, sizeof(T) * 8 ) );
}
I need to ensure that the StoreBits method is not compiled when T is an enumeration. Simply avoiding it at runtime with a branch isn't enough.
Test to see if the type is an enum and if it's not convertible to
u32
. This allows you to distinguish between normalenum
andenum class
. If it's an enum but is not convertible tou32
, then it's anenum class
:Since your
StoreEnum
andStoreBits
function templates can't take both, you need to useif constexpr
here to avoid the type check when compiling.