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 normalenumandenum class. If it's an enum but is not convertible tou32, then it's anenum class:Since your
StoreEnumandStoreBitsfunction templates can't take both, you need to useif constexprhere to avoid the type check when compiling.