I'm trying to avoid a rather complex inheritance chain for a set of plain old data structs, but I need to store them all in a vector + share ownership with the caller.
Struct A {};
Struct B {};
using TInstruction = std::variant<A, B>;
struct holder {
std::vector<std::shared_ptr<TInstruction>> items;
};
static holder h;
// Every individual TInstruction gets its own add function, for validation purposes
void add(std::shared_ptr<A> a) {
// Somehow add this to h, while still sharing ownership with the caller
// h.emplace_back(???)
}
int main() {
holder h;
auto a = std::make_unique<A>();
auto b = std::make_unique<B>();
add(a);
// add(b) // not implemented
}
I've had moderate (but annoyingly poor) success with the following changes to the original idea:
- Use shared pointers inside the variant, i.e.
using TInstruction = std::variant<std::shared_ptr<A>, std::shared_ptr<B>> - Accepting a std::weak_ptr in
add()and use.lock()to turn it into a std::shared_ptr
I don't mind #2 (it seems to me that it might be the right way to do it), but keeping the shared_ptr inside the variant inside of "outside" of it leads to some very verbose code and pattern matching.
Is it possible to do this at all? I essentially want to change the type of the shared pointer, but still express the idea of shared ownership.