C++ should have a bit_cast function.

bit_cast<T>(x) would get the bits of x, and reinterpret them as the bits of a value of type T.

For example, you would be able to write

float x = 1.0f;
const uint32_t y = bit_cast<uint32_t>(x);

And then y would have the value 0x3f800000.

From a generated-code point of view this would be a no-op. (Or maybe some instructions would have to be emitted for moving to/from floating point registers in this case?)

Edit: A bit_cast is only valid if the source and destination types are the same size. Using bit_cast on types differing in size would give a compile-time error.

This kind of bit conversion needs to be done pretty often if you are writing low-level, high peformance code, or networking code.

There are a number of ways to do something similar with C++ today, but they all have problems, either with correctness or elegance.

### Current option 1: pointer casting

Possibly the most old-school way is to pointer cast, like this:
float x = 1.0f;
const uint32_t y = *(uint32_t*)&x;

The problem here is that it is undefined behaviour to write through one pointer type (float*) and read through another (uint32_t*). (due to aliasing rules). Compilers may whinge about it and/or generate code that does not do what you want. For example, GCC says

"warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]"

(see code example here: https://goo.gl/wZcV2D).

### Current option 2: union abusing

The trick here is to write into one of the union fields, then read from the other one.
float x = 1.0f;

union fi_union
{
float f;
uint32_t i;
};

fi_union u;
u.f = x;
const uint32_t y = u.i;

This *may* work in practice, but is syntactically ugly, is an abuse of the idea of unions, and may be undefined behaviour.

### Current option 3: memcpy

The idea here is to just memcpy() from the src to the dest, and rely on the compiler to recognise what you are doing, and to not actually emit the memcpy function call. Example:
template <class Src, class Dest>
inline Dest bit_cast(const Src& x)
{
static_assert(sizeof(Src) == sizeof(Dest), "sizeof(Src) == sizeof(Dest)");
Dest d;
std::memcpy(&d, &x, sizeof(Dest));
return d;
}

This works well in practice, but is a little dangerous in the sense that you are relying on a compiler optimisation to avoid very slow code (e.g. it would be very slow if a function call was actually emitted).

### Current (non-)option 4: static_cast

static_cast does not do what we want.
float x = 1.0f;
const uint32_t y = static_cast<uint32_t>(x);

puts the value '1' in y, not 0x3f800000 as we want.

### Current (non-)option 5: reinterpret_cast

To be honest I'm not sure what reinterpret_cast is for. I never use it. It also doesn't do what we want:
float x = 1.0f;
const uint32_t y = reinterpret_cast<uint32_t>(x);

gives, in Visual Studio 2012: "error C2440: 'reinterpret_cast' : cannot convert from 'float' to 'uint32_t' Conversion is a valid standard conversion, which can be performed implicitly or by use of static_cast, C-style cast or function-style cast"

### Semantics

The bit_cast would give the same result as the bit_cast function above:

template <class Src, class Dest>
inline Dest bit_cast(const Src& x)
{
static_assert(sizeof(Src) == sizeof(Dest), "sizeof(Src) == sizeof(Dest)");
Dest d;
std::memcpy(&d, &x, sizeof(Dest));
return d;
}

Because we know 'd' (the destination) is in a different memory location from 'x' (the source), there shouldn't be any aliasing problems.

### Conclusion

So in conclusion, the alternatives are basically hacky workarounds to something missing in the original language. Older alternatives are increasingly rendered invalid due to fussier optimising compilers. I think the problem should be solved once and for all with a built-in language feature - bit_cast.

Edit: reddit discussion here.

Edit: posted to 'ISO C++ Standard - Future Proposals' list here.