'Converting struct to unique_ptr from struct member
So in part of a larger refactoring, I need to assert that a certain struct is_standard_layout because of communication between server client. Consider the following:
struct CommonHeader
{
uint32_t m1;
uint32_t headerSize;
};
Previously all other headers had derived from this like so:
// old style
struct OtherHeaderOld : public CommonHeader
{
// CommonHeader placed here implicitly with gcc compiler.
uint32_t m2;
};
But this does not guarantee standard_layout. Until now the compilers we've used luckily placed the base as the first member. For the refactoring I'd like to do this:
// new style
struct OtherHeaderNew
{
CommonHeader header; // placed here instead of inheriting. Same layout as old struct with gcc.
uint32_t m2;
std::unique_ptr<CommonHeader> ToUniqueHeader()
{
return std::unique_ptr<CommonMessageHeader>(&header);
}
};
So far, this should all be equivalent in layout. However, at some point in the code I need to transfer this header to a unique_ptr<CommonHeader>.
Before this was easily done with:
// old style header here
auto uOtherPtr = std::make_unique<OtherHeaderOld>();
// do some init code here
// do implicit conversion is no problem
// since it is derived from CommonHeader
unique_ptr<CommonHeader> uPtr = uOtherPtr;
// send the msg based on the CommonHeader
Dipatch(uPtr);
Now, with the new version of the header I'd like to do:
// new style header here
auto uOtherPtr = std::make_unique<OtherHeaderNew>();
// do some init code here
// no use of auto here to emphasize the conversion to CommonHeader
// this will compile, but will the UniquePtr clean up the whole object correctly?
unique_ptr<CommonHeader> uPtr = uOtherPtr->ToUniqueHeader();
// send the msg based on the CommonHeader
Dipatch(uPtr);
This compiles without a problem. So finally the question: Is this a legal way to convert to a unique_ptr?
Update Some people suggested that deleting via the first member was different than deleting the ptr to the object. I tried this with GCC here, https://godbolt.org/z/vzncsGbGY And it seems to produce the exact same output (try to switch with DELETE_VIA_FIRST_MEMBER)
P.S.
I tried to look at the documentation, but couldn't find out the appropriate place to look for the rules underlying this, so any reference will be very welcome.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
