【发布时间】:2021-05-07 01:28:58
【问题描述】:
我正在尝试编写一个模板化函数,该函数将允许我传入一个显式大小的枚举,它会根据 C++ 11 中枚举的大小调用正确的序列化函数。这是我目前拥有的,工作正常:
template<typename EnumName>
uint32_t WriteBuffer::Write_enum(EnumName aValue)
{
constexpr uint32_t cNumBits = sizeof(EnumName) * 8;
switch(cNumBits)
{
case 8:
{
return Write_uint8(static_cast<uint8_t>(aValue));
}
break;
case 16:
{
return Write_uint16(static_cast<uint16_t>(aValue));
}
break;
case 64:
{
return Write_uint64(static_cast<uint64_t>(aValue));
}
break;
case 32:
default:
{
return Write_uint32(static_cast<uint32_t>(aValue));
}
break;
}
}
enum MyEnum : uint8_t
{
A,
B
}
void SomeFunction()
{
m_writeBuffer.Write_enum(m_myEnum);
}
但是,这仍然需要一些运行时工作来运行开关。我很好奇模板是否可用于确定在编译时调用的正确内容,因为枚举的大小在编译时是已知的。像这样的东西,虽然这显然不起作用:
template<typename EnumName>
uint32_t WriteBuffer::Write_enum(EnumName aValue)
{
constexpr uint32_t cNumBits = sizeof(EnumName) * 8;
Write_sizedenum<EnumName, cNumBits>(aValue);
}
template<typename EnumName, 8>
uint32_t WriteBuffer::Write_sizedenum(EnumName aValue)
{
return Write_uint8(static_cast<uint8_t>(aValue));
}
template<typename EnumName, 16>
uint32_t WriteBuffer::Write_sizedenum(EnumName aValue)
{
return Write_uint16(static_cast<uint16_t>(aValue));
}
// etc
请注意,出于代码生成的原因,我不知道编写调用 Write_enum 的代码的枚举的大小,因此我需要重载和模板的某种组合,这样我就可以使用一个名称调用一个函数适用于所有枚举大小。
这可能与模板有关吗?还是运行时切换是我能做的最好的?
【问题讨论】:
-
代码生成与否,当您可以将
EnumName类型的值传递给函数时,您也可以传递sizeof(EnumName)。不过,最好在编译时就使用该信息。 -
由于
cNumBits是constexpr,您可以进行一系列if constexpr (cNumBits == 8)、else if constexpr (cNumBits == 16)等检查,而不是switch,这将在编译时进行评估.