I have a class with two members.
class C {
typeA a;
typeB b;
};
Assume that there is no inheritance. There are three things I'm concerned about with this class.
- the order in which the constructors for
aandbare called - the order in which the destructors for
aandbare called - the layout of
aandbin memory
One reason I may care about (1) and (2) is thread synchronization. Some reasons I may care about (3) are:
padding
spatial locality with more than two class members
the first class member has memory offset 0
I want to be able to control (1)-(3) simultaneously. However, it seems that when I choose an order in memory, I also choose the order of the constructors and destructors. Is there a way to have control over (1)-(3) simultaneously?
Yes. Spell each individual member like this:
This prevents them from being automatically constructed and destructed, allowing you to do it manually (
::new((void *)&a) typeA();to construct,a.~typeA();to destruct).Obligatory reminder that if you have exceptions enabled and
C's constructor is notnoexcept, and one of the constructors throws, you need to destroy the members that were already constructed.Took this as a challenge, wrote a tuple class with this feature:
Implementation is below.
While it seems to work well so far, even in presence of exceptions, if you're going to use it in production, it's your job to cover it with tests to make sure I didn't mess up the RAII.
This requires C++23, but backporting to C++20 shouldn't be hard. (Or to C++17 if you get rid of the string keys.)