out of curiosity, can you elaborate on that a bit? I've shipped std::variant in a few designs and it's been OK, but maybe I didn't use it deeply enough to see issues.
std::variant has valueless_by_exception - the C++ language wasn't able to ensure that your variant of a Dog or a Cat is always, in fact, a Dog or a Cat, in some cases it's neither so... here's valueless_by_exception instead, sorry.
If neither Dog or Cat have throwing constructors, then std::variant<Dog, Cat> is guaranteed to always be a Dog or a Cat.
Any need here for an allocator is due to a language defect. Rather than implement a fix for the C++ programming language they just punted this problem to every C++ programmer. That's the New Jersey style.