This is mainly to illustrate the idea; I don't claim any correctness or good performance from this code. (if you do inserts after reading a [] you may invalidate some pointers!)
impl_X is your base class with most of your logic. interface is used to pull out just the parts of the data that you might work with while wanting to have it in SoA format. Then we specialize the vector template for the interface to give us a dummy class with the things we need, but that sends our writes back to the backing array.
If we need to get an individual struct out of it the conversion is automatic. If we just need to access some member vars it will (hopefully) optimize down to direct accesses. We do bear some complexity in implementation, but it's all confined here.
I'm now realizing I was a bit imprecise in my earlier comment. the specialized vector is not around <yourclass> but around an interface parent of your class. You could also just specialize yourclass vector, but then you don't have the ability to switch.
https://pastebin.com/aZWTAL2J
impl_X is your base class with most of your logic. interface is used to pull out just the parts of the data that you might work with while wanting to have it in SoA format. Then we specialize the vector template for the interface to give us a dummy class with the things we need, but that sends our writes back to the backing array.
If we need to get an individual struct out of it the conversion is automatic. If we just need to access some member vars it will (hopefully) optimize down to direct accesses. We do bear some complexity in implementation, but it's all confined here.
I'm now realizing I was a bit imprecise in my earlier comment. the specialized vector is not around <yourclass> but around an interface parent of your class. You could also just specialize yourclass vector, but then you don't have the ability to switch.