Reputation: 161
Is it possible to do this?
struct compound_type {
int member;
};
void func()
{
compound_type foo {384};
int bar = sole_member_type_cast<int>(foo); // doesn't compile; there's no such thing
// reinterpret_cast wouldn't compile here
std::cout << bar << std::endl; // prints 384
}
I know it's possible with pointer aliasing, but it seems like this is a strict aliasing problem. (Is it?) Unions are also used, but again you aren't supposed to do so, as a union type "can hold only one of its non-static data members at a time" (ref).
In any case, would there be alignment or offset problems with this?
Upvotes: 0
Views: 270
Reputation: 40881
A simple way to cast between a struct with one public non-static member and that member is to use a structured binding:
auto [bar] = foo; // auto& to not copy
assert(bar == 384);
This works with non-standard-layout types too. For example, if compound_type::member
was an int&
or a std::vector<int>
, &foo
and &foo.member
would no longer be pointer-interconvertible.
Upvotes: 2
Reputation: 60278
Yes, you can do:
int bar = *reinterpret_cast<int*>(&foo);
This is well defined since objects of compound_type
and int
are pointer-inter-convertible. The address of foo
is the same as the address of its first data member which is an int
, and so the reinterpret_cast
is well defined.
As pointed out in the comments by @Remy Lebeau, the conversion could be simplified to:
int bar = reinterpret_cast<int&>(foo);
which is much easier to read, and write.
Upvotes: 1