繁体   English   中英

通过引用修改范围枚举

[英]Modifying scoped enum by reference

我越来越多地发现使用范围难以使用的enums。 我正在尝试编写一组函数重载,包括用于通过引用设置/初始化值的作用域枚举模板 - 如下所示:

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);
}

我相信除了raw_val之外, static_cast引入了第二个临时值。 我认为编译器可能会优化其中的一个或两个,并且在任何情况下它都不应该在性能方面产生太大的影响,因为set_value调用也会生成临时值(假设它没有内联),但这似乎仍然不够优雅。 我想这样做会是这样的:

template <typename ENUM>
set_value(ENUM& val)
{
  set_value(static_cast<std::underlying_type_t<ENUM>&>(val));
}

...但这是无效的(相应的代码也不是直接使用指针而不是引用),因为作用域的枚举通过继承与它们的底层基元无关。

我可以使用reinterpret_cast ,从一些初步测试看起来似乎有效(我想不出任何原因导致它不起作用),但这似乎在C ++中不受欢迎。

是否有“标准”方法来做到这一点?

我可以使用reinterpret_cast ,从一些初步测试看起来似乎有效(我想不出任何原因导致它不起作用),但这似乎在C ++中不受欢迎。

实际上, reinterpret_cast是违反严格别名规则的未定义行为。

消除单个mov指令(或者或多或少,复制寄存器的数据)是过早的微优化。 编译器很可能能够处理它。

如果性能非常重要,那么请遵循优化过程:配置文件,反汇编,理解编译器的解释,并在定义的规则中与它一起工作。

乍一看,您(和编译器)可能更容易使用T get_value()等函数而不是void set_value(T) 虽然丢失了类型推导,但数据流和初始化更有意义。 如果这非常重要,您可以通过标签类型重新获得扣除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM