For both cases I think it's less that there isn't convenient syntax for it, and more that the generality of the syntax doesn't restrict you enough to enforce the pattern. For example, you can do a decent job approximating a monadic state machine system in C++14 with just optional and structs, so long as you follow the rule that all mutable state is kept in a state struct and all business logic must be in the form of functions with the signature optional<state>(const state&). Hell, you could even remove the optional if you don't consider there to be any "failure" cases, just cases that don't mutate the state
Then, you can use any container you like to keep track of your valid state transitions and not even have to use polymorphism. But of course C++ gives you many ways in which to trivially break this nice system of guarantees, including mutable lambdas, or even just implicit reliance on fixed memory addresses via explicit allocation and pointers in an external scope. This pattern is very general, so it's hard to capture in a guardrail
Then, you can use any container you like to keep track of your valid state transitions and not even have to use polymorphism. But of course C++ gives you many ways in which to trivially break this nice system of guarantees, including mutable lambdas, or even just implicit reliance on fixed memory addresses via explicit allocation and pointers in an external scope. This pattern is very general, so it's hard to capture in a guardrail