Modifying a Covered Enumeration by Reference

Increasingly, I find embossed areas that cannot be used. I'm trying to write a set of function overloads including a template for copied enums that sets / initializes a value by reference - something like this:

void set_value(int& val);
void set_value(double& val);
template <typename ENUM> set_value(ENUM& val);

      

However, I am not quite clear on how to write a templated version set_value

without entering multiple temp values:

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

      

I believe it static_cast

introduces a second temporary value in addition to raw_val

. I suppose it is possible that one or both of them could be optimized by the compiler, and it shouldn't make much of a difference in terms of performance anyway, since the call set_value

also generates temp values ​​(assuming it's not inline), but this still seems inelegant. What I would like to do would be something like this:

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

      

... but this is not valid (and no relevant code using pointers directly instead of references), since cloud enums are not linked to their base primitives via inheritance.

I could use reinterpret_cast

which, according to some preliminary testing, works (and I can't think of any reason why it won't work), but in C ++ it seems frowned upon.

Is there a "standard" way to do this?

+3


source to share


1 answer


I could use reinterpret_cast

which, according to some preliminary testing, works (and I can't think of any reason why it won't work), but in C ++ it seems to be unhappy.

Indeed, what reinterpret_cast

is undefined behavior for breaking the strict anti-aliasing rule.

Eliminating one instruction mov

(or, conversely, more or less copying data in a register) is a premature micro-optimization. The compiler will most likely be able to take care of this.



If performance is really important, follow the optimization process: profile, disassemble, understand the compiler's interpretation, and work with it within certain rules.

At first glance, you (and the compiler) may have an easier time with type functions T get_value()

instead of void set_value(T)

. Data flow and initialization make more sense, although type inference is lost. You can recover the deduction through tags if it really matters.

0


source







All Articles