我越来越多地发现使用范围难以使用的枚举枚举。我正在尝试编写一组函数重载,包括用于通过引用设置/初始化值的作用域枚举模板 - 如下所示:
void set_value(int& val);
void set_value(double& val);
template <typename ENUM> set_value(ENUM& val);
但是,我不太清楚如何在不引入多个临时值的情况下编写set_value
的模板版本:
template <typename ENUM>
set_value(ENUM& val)
{
std::underlying_type_t<ENUM> raw_val;
set_value(raw_val); // Calls the appropriate "primitive" overload
val = static_cast<ENUM>(raw_val);
}
我认为static_cast
除了raw_val
之外还引入了第二个临时值。我认为编译器可能会优化其中的一个或两个,并且在任何情况下它都不应该在性能方面做出很大的改变,因为set_value
调用也会生成临时值(假设它没有内联),但这似乎仍然不够优雅。我喜欢做的事情是这样的:
template <typename ENUM>
set_value(ENUM& val)
{
set_value(static_cast<std::underlying_type_t<ENUM>&>(val));
}
...但是这不是有效的(相应的代码也不是直接使用指针而不是引用),因为作用域的枚举不是通过继承与它们的底层基元相关。
我可以使用reinterpret_cast
,这可以从一些初步测试中看起来有用(而且我无法想出它为什么不起作用的任何理由),但这似乎是皱眉头在C ++中。
是否有&#34;标准&#34;这样做的方法?
答案 0 :(得分:0)
我可以使用
reinterpret_cast
,这可以从一些初步测试中看起来有效(我想不出任何原因导致它不起作用),但这似乎在C ++中不受欢迎。
实际上,reinterpret_cast
是违反严格别名规则的未定义行为。
消除单个mov
指令(或者更多或更少,复制寄存器的数据)是过早的微优化。编译器很可能能够处理它。
如果性能非常重要,那么请遵循优化过程:配置文件,反汇编,理解编译器的解释,并在定义的规则中与它一起工作。
乍一看,您(和编译器)可能更容易使用T get_value()
而不是void set_value(T)
等功能。虽然丢失了类型推导,但数据流和初始化更有意义。如果这非常重要,您可以通过标签类型重新获得扣除。